KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > timer > Timer


1 /*
2  * @(#)Timer.java 4.58 04/04/13
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management.timer;
9
10
11
12 // java imports
13
//
14
import java.util.Date JavaDoc;
15 import java.util.Enumeration JavaDoc;
16 import java.util.Hashtable JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Set JavaDoc;
19 import java.util.TreeSet JavaDoc;
20 import java.util.Vector JavaDoc;
21
22 // jmx imports
23
//
24
import javax.management.MBeanNotificationInfo JavaDoc;
25 import javax.management.MBeanRegistration JavaDoc;
26 import javax.management.MBeanServer JavaDoc;
27 import javax.management.NotificationBroadcasterSupport JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29 import javax.management.InstanceNotFoundException JavaDoc;
30
31 import com.sun.jmx.trace.Trace;
32
33 /**
34  *
35  * Provides the implementation of the timer MBean.
36  * The timer MBean sends out an alarm at a specified time
37  * that wakes up all the listeners registered to receive timer notifications.
38  * <P>
39  *
40  * This class manages a list of dated timer notifications.
41  * A method allows users to add/remove as many notifications as required.
42  * When a timer notification is emitted by the timer and becomes obsolete,
43  * it is automatically removed from the list of timer notifications.
44  * <BR>Additional timer notifications can be added into regularly repeating notifications.
45  * <P>
46  *
47  * Note:
48  * <OL>
49  * <LI>All notifications before the time when the <CODE>addNotification</CODE> method is called
50  * are ignored, irrespective of the <CODE>sendPastNotifications</CODE> flag.
51  * <LI>When sending timer notifications, the timer updates the notification sequence number
52  * irrespective of the notification type.
53  * <LI>The timer service relies on the system date of the host where the <CODE>Timer</CODE> class is loaded.
54  * Listeners may receive untimely notifications
55  * if their host has a different system date.
56  * To avoid such problems, synchronize the system date of all host machines where timing is needed.
57  * <LI>The default behavior for periodic notifications is <i>fixed-delay execution</i>, as
58  * specified in {@link java.util.Timer}. In order to use <i>fixed-rate execution</i>, use the
59  * overloaded {@link #addNotification(String, String, Object, Date, long, long, boolean)} method.
60  * <LI>Notification listeners are potentially all executed in the same
61  * thread. Therefore, they should execute rapidly to avoid holding up
62  * other listeners or perturbing the regularity of fixed-delay
63  * executions. See {@link NotificationBroadcasterSupport}.
64  * </OL>
65  *
66  * @version 4.58 04/13/04
67  * @author Sun Microsystems, Inc
68  *
69  * @since 1.5
70  */

71 public class Timer extends NotificationBroadcasterSupport JavaDoc
72     implements TimerMBean JavaDoc, MBeanRegistration JavaDoc {
73
74     
75     /*
76      * ------------------------------------------
77      * PUBLIC VARIABLES
78      * ------------------------------------------
79      */

80
81     /**
82      * Number of milliseconds in one second.
83      * Useful constant for the <CODE>addNotification</CODE> method.
84      */

85     public static final long ONE_SECOND = 1000;
86
87     /**
88      * Number of milliseconds in one minute.
89      * Useful constant for the <CODE>addNotification</CODE> method.
90      */

91     public static final long ONE_MINUTE = 60*ONE_SECOND;
92
93     /**
94      * Number of milliseconds in one hour.
95      * Useful constant for the <CODE>addNotification</CODE> method.
96      */

97     public static final long ONE_HOUR = 60*ONE_MINUTE;
98
99     /**
100      * Number of milliseconds in one day.
101      * Useful constant for the <CODE>addNotification</CODE> method.
102      */

103     public static final long ONE_DAY = 24*ONE_HOUR;
104
105     /**
106      * Number of milliseconds in one week.
107      * Useful constant for the <CODE>addNotification</CODE> method.
108      */

109     public static final long ONE_WEEK = 7*ONE_DAY;
110
111
112     // TRACES & DEBUG
113
//---------------
114

115     boolean isTraceOn() {
116         return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_TIMER);
117     }
118
119     void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
120         Trace.send(Trace.LEVEL_TRACE, Trace.INFO_TIMER, clz, func, info);
121     }
122
123     void trace(String JavaDoc func, String JavaDoc info) {
124         trace(dbgTag, func, info);
125     }
126     
127     boolean isDebugOn() {
128         return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_TIMER);
129     }
130
131     void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
132         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_TIMER, clz, func, info);
133     }
134
135     void debug(String JavaDoc func, String JavaDoc info) {
136         debug(dbgTag, func, info);
137     }
138     
139
140     /*
141      * ------------------------------------------
142      * PRIVATE VARIABLES
143      * ------------------------------------------
144      */

145
146     private static final String JavaDoc dbgTag = "Timer";
147     
148     /**
149      * Table containing all the timer notifications of this timer,
150      * with the associated date, period and number of occurrences.
151      */

152     private Hashtable JavaDoc timerTable = new Hashtable JavaDoc();
153     
154     /**
155      * Past notifications sending on/off flag value.
156      * This attribute is used to specify if the timer has to send past notifications after start.
157      * <BR>The default value is set to <CODE>false</CODE>.
158      */

159     private boolean sendPastNotifications = false;
160     
161     /**
162      * Timer state.
163      * The default value is set to <CODE>false</CODE>.
164      */

165     private transient boolean isActive = false;
166     
167     /**
168      * Timer sequence number.
169      * The default value is set to 0.
170      */

171     private transient long sequenceNumber = 0;
172     
173     // Flags needed to keep the indexes of the objects in the array.
174
//
175
private static final int TIMER_NOTIF_INDEX = 0;
176     private static final int TIMER_DATE_INDEX = 1;
177     private static final int TIMER_PERIOD_INDEX = 2;
178     private static final int TIMER_NB_OCCUR_INDEX = 3;
179     private static final int ALARM_CLOCK_INDEX = 4;
180     private static final int FIXED_RATE_INDEX = 5;
181
182     /**
183      * The notification counter ID.
184      * Used to keep the max key value inserted into the timer table.
185      */

186     private int counterID = 0;
187
188     private java.util.Timer JavaDoc timer;
189
190     /*
191      * ------------------------------------------
192      * CONSTRUCTORS
193      * ------------------------------------------
194      */

195
196     /**
197      * Default constructor.
198      */

199     public Timer() {
200     }
201   
202     /*
203      * ------------------------------------------
204      * PUBLIC METHODS
205      * ------------------------------------------
206      */

207     
208     /**
209      * Allows the timer MBean to perform any operations it needs before being registered
210      * in the MBean server.
211      * <P>
212      * Not used in this context.
213      *
214      * @param server The MBean server in which the timer MBean will be registered.
215      * @param name The object name of the timer MBean.
216      *
217      * @return The name of the timer MBean registered.
218      *
219      * @exception java.lang.Exception
220      */

221     public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
222         throws java.lang.Exception JavaDoc {
223         return name;
224     }
225             
226     /**
227      * Allows the timer MBean to perform any operations needed after having been
228      * registered in the MBean server or after the registration has failed.
229      * <P>
230      * Not used in this context.
231      */

232     public void postRegister (Boolean JavaDoc registrationDone) {
233     }
234
235     /**
236      * Allows the timer MBean to perform any operations it needs before being unregistered
237      * by the MBean server.
238      * <P>
239      * Stops the timer.
240      *
241      * @exception java.lang.Exception
242      */

243     public void preDeregister() throws java.lang.Exception JavaDoc {
244         
245         if (isTraceOn()) {
246             trace("preDeregister", "stop the timer");
247         }
248         
249         // Stop the timer.
250
//
251
stop();
252     }
253
254     /**
255      * Allows the timer MBean to perform any operations needed after having been
256      * unregistered by the MBean server.
257      * <P>
258      * Not used in this context.
259      */

260     public void postDeregister() {
261     }
262
263     /*
264      * This overrides the method in NotificationBroadcasterSupport.
265      * Return the MBeanNotificationInfo[] array for this MBean.
266      * The returned array has one element to indicate that the MBean
267      * can emit TimerNotification. The array of type strings
268      * associated with this entry is a snapshot of the current types
269      * that were given to addNotification.
270      */

271     public synchronized MBeanNotificationInfo JavaDoc[] getNotificationInfo() {
272     Set JavaDoc/*<String>*/ notifTypes = new TreeSet JavaDoc();
273     for (Iterator JavaDoc it = timerTable.values().iterator(); it.hasNext(); ) {
274         Object JavaDoc[] entry = (Object JavaDoc[]) it.next();
275         TimerNotification JavaDoc notif = (TimerNotification JavaDoc)
276         entry[TIMER_NOTIF_INDEX];
277         notifTypes.add(notif.getType());
278     }
279     String JavaDoc[] notifTypesArray = (String JavaDoc[])
280         notifTypes.toArray(new String JavaDoc[0]);
281     return new MBeanNotificationInfo JavaDoc[] {
282         new MBeanNotificationInfo JavaDoc(notifTypesArray,
283                       TimerNotification JavaDoc.class.getName(),
284                       "Notification sent by Timer MBean")
285     };
286     }
287
288     /**
289      * Starts the timer.
290      * <P>
291      * If there is one or more timer notifications before the time in the list of notifications, the notification
292      * is sent according to the <CODE>sendPastNotifications</CODE> flag and then, updated
293      * according to its period and remaining number of occurrences.
294      * If the timer notification date remains earlier than the current date, this notification is just removed
295      * from the list of notifications.
296      */

297     public synchronized void start() {
298         
299         if (isTraceOn()) {
300             trace("start", "starting the timer");
301         }
302         
303         // Start the TimerAlarmClock.
304
//
305
if (isActive == false) {
306           
307         timer = new java.util.Timer JavaDoc();
308
309             TimerAlarmClock JavaDoc alarmClock;
310             Object JavaDoc[] obj;
311             Date JavaDoc date;
312         
313             Date JavaDoc currentDate = new Date JavaDoc();
314            
315             // Send or not past notifications depending on the flag.
316
// Update the date and the number of occurrences of past notifications
317
// to make them later than the current date.
318
//
319
sendPastNotifications(currentDate, sendPastNotifications);
320            
321             // Update and start all the TimerAlarmClocks.
322
// Here, all the notifications in the timer table are later than the current date.
323
//
324
Enumeration JavaDoc e = timerTable.elements();
325             while (e.hasMoreElements()) {
326                  
327                 obj = (Object JavaDoc[])e.nextElement();
328                  
329                 // Retrieve the date notification and the TimerAlarmClock.
330
//
331
date = (Date JavaDoc)obj[TIMER_DATE_INDEX];
332                  
333                 // Update all the TimerAlarmClock timeouts and start them.
334
//
335
boolean fixedRate = ((Boolean JavaDoc)obj[FIXED_RATE_INDEX]).booleanValue();
336                 if (fixedRate)
337                 {
338                   alarmClock = new TimerAlarmClock JavaDoc(this, date);
339                   obj[ALARM_CLOCK_INDEX] = (Object JavaDoc)alarmClock;
340                   timer.schedule(alarmClock, alarmClock.next);
341                 }
342                 else
343                 {
344                   alarmClock = new TimerAlarmClock JavaDoc(this, (date.getTime() - currentDate.getTime()));
345                   obj[ALARM_CLOCK_INDEX] = (Object JavaDoc)alarmClock;
346                   timer.schedule(alarmClock, alarmClock.timeout);
347                 }
348             }
349            
350             // Set the state to ON.
351
//
352
isActive = true;
353         
354             if (isTraceOn()) {
355                 trace("start", "timer started");
356             }
357         } else {
358             if (isTraceOn()) {
359                 trace("start", "the timer is already activated");
360             }
361         }
362     }
363
364     /**
365      * Stops the timer.
366      */

367     public synchronized void stop() {
368         
369         if (isTraceOn()) {
370             trace("stop", "stoping the timer");
371         }
372         
373         // Stop the TimerAlarmClock.
374
//
375
if (isActive == true) {
376           
377             TimerAlarmClock JavaDoc alarmClock;
378             Object JavaDoc[] obj;
379           
380             Enumeration JavaDoc e = timerTable.elements();
381             while (e.hasMoreElements()) {
382                 
383                 obj = (Object JavaDoc[])e.nextElement();
384                 
385                 // Stop all the TimerAlarmClock.
386
//
387
alarmClock = (TimerAlarmClock JavaDoc)obj[ALARM_CLOCK_INDEX];
388                 if (alarmClock != null) {
389 // alarmClock.interrupt();
390
// try {
391
// // Wait until the thread die.
392
// //
393
// alarmClock.join();
394
// } catch (InterruptedException ex) {
395
// // Ignore...
396
// }
397
// // Remove the reference on the TimerAlarmClock.
398
// //
399

400             alarmClock.cancel();
401                     alarmClock = null;
402                 }
403             }
404           
405             timer.cancel();
406
407             // Set the state to OFF.
408
//
409
isActive = false;
410             
411             if (isTraceOn()) {
412                 trace("stop", "timer stopped");
413             }
414         } else {
415             if (isTraceOn()) {
416                 trace("stop", "the timer is already deactivated");
417             }
418         }
419     }
420             
421     /**
422      * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
423      * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date,
424      * period and number of occurrences.
425      * <P>
426      * If the timer notification to be inserted has a date that is before the current date,
427      * the method behaves as if the specified date were the current date. <BR>
428      * For once-off notifications, the notification is delivered immediately. <BR>
429      * For periodic notifications, the first notification is delivered immediately and the
430      * subsequent ones are spaced as specified by the period parameter.
431      * <P>
432      * Note that once the timer notification has been added into the list of notifications,
433      * its associated date, period and number of occurrences cannot be updated.
434      * <P>
435      * In the case of a periodic notification, the value of parameter <i>fixedRate</i> is used to
436      * specify the execution scheme, as specified in {@link java.util.Timer}.
437      *
438      * @param type The timer notification type.
439      * @param message The timer notification detailed message.
440      * @param userData The timer notification user data object.
441      * @param date The date when the notification occurs.
442      * @param period The period of the timer notification (in milliseconds).
443      * @param nbOccurences The total number the timer notification will be emitted.
444      * @param fixedRate If <code>true</code> and if the notification is periodic, the notification
445      * is scheduled with a <i>fixed-rate</i> execution scheme. If
446      * <code>false</code> and if the notification is periodic, the notification
447      * is scheduled with a <i>fixed-delay</i> execution scheme. Ignored if the
448      * notification is not periodic.
449      *
450      * @return The identifier of the new created timer notification.
451      *
452      * @exception java.lang.IllegalArgumentException The period or the number of occurrences is negative
453      *
454      * @see #addNotification(String, String, Object, Date, long, long)
455      */

456 // NPCTE fix for bugId 4464388, esc 0, MR, to be added after modification of jmx spec
457
// public synchronized Integer addNotification(String type, String message, Serializable userData,
458
// Date date, long period, long nbOccurences)
459
// end of NPCTE fix for bugId 4464388
460

461     public synchronized Integer JavaDoc addNotification(String JavaDoc type, String JavaDoc message, Object JavaDoc userData,
462                                                 Date JavaDoc date, long period, long nbOccurences, boolean fixedRate)
463         throws java.lang.IllegalArgumentException JavaDoc {
464         
465         if (date == null) {
466             throw new java.lang.IllegalArgumentException JavaDoc("Timer notification date cannot be null.");
467         }
468         
469         // Check that all the timer notification attributes are valid.
470
//
471

472         // Invalid timer period value exception:
473
// Check that the period and the nbOccurences are POSITIVE VALUES.
474
//
475
if ((period < 0) || (nbOccurences < 0)) {
476             throw new java.lang.IllegalArgumentException JavaDoc("Negative values for the periodicity");
477         }
478         
479         Date JavaDoc currentDate = new Date JavaDoc();
480                         
481         // Update the date if it is before the current date.
482
//
483
if (currentDate.after(date)) {
484             
485           date.setTime(currentDate.getTime());
486           if (isTraceOn()) {
487             trace("addNotification", "update timer notification to add with:" +
488                   "\n\tNotification date = " + date);
489           }
490         }
491           
492         // Create and add the timer notification into the timer table.
493
//
494
Integer JavaDoc notifID = null;
495         notifID = new Integer JavaDoc(++counterID);
496         
497         // The sequenceNumber and the timeStamp attributes are updated
498
// when the notification is emitted by the timer.
499
//
500
TimerNotification JavaDoc notif = new TimerNotification JavaDoc(type, this, 0, 0, message, notifID);
501         notif.setUserData(userData);
502         
503         Object JavaDoc[] obj = new Object JavaDoc[6];
504         
505         TimerAlarmClock JavaDoc alarmClock;
506         if (fixedRate)
507         {
508           alarmClock = new TimerAlarmClock JavaDoc(this, date);
509         }
510         else
511         {
512           alarmClock = new TimerAlarmClock JavaDoc(this, (date.getTime() - currentDate.getTime()));
513         }
514
515         // Fix bug 00417.B
516
// The date registered into the timer is a clone from the date parameter.
517
//
518
Date JavaDoc d = new Date JavaDoc(date.getTime());
519                 
520         obj[TIMER_NOTIF_INDEX] = (Object JavaDoc)notif;
521         obj[TIMER_DATE_INDEX] = (Object JavaDoc)d;
522         obj[TIMER_PERIOD_INDEX] = (Object JavaDoc) new Long JavaDoc(period);
523         obj[TIMER_NB_OCCUR_INDEX] = (Object JavaDoc) new Long JavaDoc(nbOccurences);
524         obj[ALARM_CLOCK_INDEX] = (Object JavaDoc)alarmClock;
525         obj[FIXED_RATE_INDEX] = new Boolean JavaDoc(fixedRate);
526                 
527         if (isTraceOn()) {
528             trace("addNotification", "adding timer notification:" +
529                   "\n\tNotification source = " + notif.getSource() +
530                   "\n\tNotification type = " + notif.getType() +
531                   "\n\tNotification ID = " + notifID +
532                   "\n\tNotification date = " + d +
533                   "\n\tNotification period = " + period +
534                   "\n\tNotification nb of occurrences = " + nbOccurences +
535                   "\n\tNotification executes at fixed rate = " + fixedRate);
536         }
537         
538         timerTable.put(notifID, obj);
539         
540         // Update and start the TimerAlarmClock.
541
//
542
if (isActive == true) {
543           if (fixedRate)
544           {
545         timer.schedule(alarmClock, alarmClock.next);
546           }
547           else
548           {
549             timer.schedule(alarmClock, alarmClock.timeout);
550           }
551         }
552         
553         if (isTraceOn()) {
554             trace("addNotification", "timer notification added");
555         }
556         return notifID;
557     }
558
559     /**
560      * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
561      * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date,
562      * period and number of occurrences.
563      * <P>
564      * If the timer notification to be inserted has a date that is before the current date,
565      * the method behaves as if the specified date were the current date. <BR>
566      * For once-off notifications, the notification is delivered immediately. <BR>
567      * For periodic notifications, the first notification is delivered immediately and the
568      * subsequent ones are spaced as specified by the period parameter.
569      * <P>
570      * Note that once the timer notification has been added into the list of notifications,
571      * its associated date, period and number of occurrences cannot be updated.
572      * <P>
573      * In the case of a periodic notification, uses a <i>fixed-delay</i> execution scheme, as specified in
574      * {@link java.util.Timer}. In order to use a <i>fixed-rate</i> execution scheme, use
575      * {@link #addNotification(String, String, Object, Date, long, long, boolean)} instead.
576      *
577      * @param type The timer notification type.
578      * @param message The timer notification detailed message.
579      * @param userData The timer notification user data object.
580      * @param date The date when the notification occurs.
581      * @param period The period of the timer notification (in milliseconds).
582      * @param nbOccurences The total number the timer notification will be emitted.
583      *
584      * @return The identifier of the new created timer notification.
585      *
586      * @exception java.lang.IllegalArgumentException The period or the number of occurrences is negative
587      *
588      * @see #addNotification(String, String, Object, Date, long, long, boolean)
589      */

590 // NPCTE fix for bugId 4464388, esc 0, MR , to be added after modification of jmx spec
591
// public synchronized Integer addNotification(String type, String message, Serializable userData,
592
// Date date, long period)
593
// end of NPCTE fix for bugId 4464388 */
594

595     public synchronized Integer JavaDoc addNotification(String JavaDoc type, String JavaDoc message, Object JavaDoc userData,
596                                                 Date JavaDoc date, long period, long nbOccurences)
597         throws java.lang.IllegalArgumentException JavaDoc {
598         
599       return addNotification(type, message, userData, date, period, nbOccurences, false);
600     }
601         
602     /**
603      * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
604      * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date
605      * and period and a null number of occurrences.
606      * <P>
607      * The timer notification will repeat continuously using the timer period using a <i>fixed-delay</i>
608      * execution scheme, as specified in {@link java.util.Timer}. In order to use a <i>fixed-rate</i>
609      * execution scheme, use {@link #addNotification(String, String, Object, Date, long, long,
610      * boolean)} instead.
611      * <P>
612      * If the timer notification to be inserted has a date that is before the current date,
613      * the method behaves as if the specified date were the current date. The
614      * first notification is delivered immediately and the subsequent ones are
615      * spaced as specified by the period parameter.
616      *
617      * @param type The timer notification type.
618      * @param message The timer notification detailed message.
619      * @param userData The timer notification user data object.
620      * @param date The date when the notification occurs.
621      * @param period The period of the timer notification (in milliseconds).
622      *
623      * @return The identifier of the new created timer notification.
624      *
625      * @exception java.lang.IllegalArgumentException The period is negative or
626      * the date notification is before the current date.
627      */

628 // NPCTE fix for bugId 4464388, esc 0, MR , to be added after modification of jmx spec
629
// public synchronized Integer addNotification(String type, String message, Serializable userData,
630
// Date date, long period)
631
// end of NPCTE fix for bugId 4464388 */
632

633     public synchronized Integer JavaDoc addNotification(String JavaDoc type, String JavaDoc message, Object JavaDoc userData,
634                                                 Date JavaDoc date, long period)
635         throws java.lang.IllegalArgumentException JavaDoc {
636         
637         return (addNotification(type, message, userData, date, period, 0));
638     }
639   
640     /**
641      * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
642      * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date
643      * and a null period and number of occurrences.
644      * <P>
645      * The timer notification will be handled once at the specified date.
646      * <P>
647      * If the timer notification to be inserted has a date that is before the current date,
648      * the method behaves as if the specified date were the current date and the
649      * notification is delivered immediately.
650      *
651      * @param type The timer notification type.
652      * @param message The timer notification detailed message.
653      * @param userData The timer notification user data object.
654      * @param date The date when the notification occurs.
655      *
656      * @return The identifier of the new created timer notification.
657      *
658      * @exception java.lang.IllegalArgumentException The date notification is before the current date.
659      */

660 // NPCTE fix for bugId 4464388, esc 0, MR, to be added after modification of jmx spec
661
// public synchronized Integer addNotification(String type, String message, Serializable userData, Date date)
662
// throws java.lang.IllegalArgumentException {
663
// end of NPCTE fix for bugId 4464388
664

665     public synchronized Integer JavaDoc addNotification(String JavaDoc type, String JavaDoc message, Object JavaDoc userData, Date JavaDoc date)
666         throws java.lang.IllegalArgumentException JavaDoc {
667
668         
669         return (addNotification(type, message, userData, date, 0, 0));
670     }
671   
672     /**
673      * Removes the timer notification corresponding to the specified identifier from the list of notifications.
674      *
675      * @param id The timer notification identifier.
676      *
677      * @exception InstanceNotFoundException The specified identifier does not correspond to any timer notification
678      * in the list of notifications of this timer MBean.
679      */

680     public synchronized void removeNotification(Integer JavaDoc id) throws InstanceNotFoundException JavaDoc {
681   
682         // Check that the notification to remove is effectively in the timer table.
683
//
684
if (timerTable.containsKey(id) == false) {
685             throw new InstanceNotFoundException JavaDoc("Timer notification to remove not in the list of notifications");
686         }
687                 
688         // Stop the TimerAlarmClock.
689
//
690
Object JavaDoc[] obj = (Object JavaDoc[])timerTable.get(id);
691         TimerAlarmClock JavaDoc alarmClock = (TimerAlarmClock JavaDoc)obj[ALARM_CLOCK_INDEX];
692         if (alarmClock != null) {
693 // alarmClock.interrupt();
694
// try {
695
// // Wait until the thread die.
696
// //
697
// alarmClock.join();
698
// } catch (InterruptedException e) {
699
// // Ignore...
700
// }
701
// // Remove the reference on the TimerAlarmClock.
702
// //
703
alarmClock.cancel();
704             alarmClock = null;
705         }
706         
707         // Remove the timer notification from the timer table.
708
//
709
if (isTraceOn()) {
710             trace("removeNotification", "removing timer notification:" +
711                   "\n\tNotification source = " + ((TimerNotification JavaDoc)obj[TIMER_NOTIF_INDEX]).getSource() +
712                   "\n\tNotification type = " + ((TimerNotification JavaDoc)obj[TIMER_NOTIF_INDEX]).getType() +
713                   "\n\tNotification ID = " + ((TimerNotification JavaDoc)obj[TIMER_NOTIF_INDEX]).getNotificationID() +
714                   "\n\tNotification date = " + obj[TIMER_DATE_INDEX] +
715                   "\n\tNotification period = " + obj[TIMER_PERIOD_INDEX] +
716                   "\n\tNotification nb of occurrences = " + obj[TIMER_NB_OCCUR_INDEX] +
717                   "\n\tNotification executes at fixed rate = " + obj[FIXED_RATE_INDEX]);
718         }
719         
720         timerTable.remove(id);
721         
722         if (isTraceOn()) {
723             trace("removeNotification", "timer notification removed");
724         }
725     }
726   
727     /**
728      * Removes all the timer notifications corresponding to the specified type from the list of notifications.
729      *
730      * @param type The timer notification type.
731      *
732      * @exception InstanceNotFoundException The specified type does not correspond to any timer notification
733      * in the list of notifications of this timer MBean.
734      */

735     public synchronized void removeNotifications(String JavaDoc type) throws InstanceNotFoundException JavaDoc {
736         
737         TimerNotification JavaDoc notif;
738         Integer JavaDoc id;
739     TimerAlarmClock JavaDoc alarmClock;
740     Object JavaDoc[] obj;
741         
742         Vector JavaDoc v = getNotificationIDs(type);
743         
744         // Check that the notification to remove is effectively in the timer table.
745
//
746
if (v.isEmpty()) {
747             throw new InstanceNotFoundException JavaDoc("Timer notifications to remove not in the list of notifications");
748         }
749         
750         Enumeration JavaDoc e = v.elements();
751         while (e.hasMoreElements()) {
752             notif = (TimerNotification JavaDoc)e.nextElement();
753             id = notif.getNotificationID();
754         obj = (Object JavaDoc[])timerTable.get(id);
755
756             timerTable.remove(id);
757
758         alarmClock = (TimerAlarmClock JavaDoc)obj[ALARM_CLOCK_INDEX];
759         if (alarmClock != null) {
760         alarmClock.cancel();
761         }
762         }
763     }
764             
765     /**
766      * Removes all the timer notifications from the list of notifications
767      * and resets the counter used to update the timer notification identifiers.
768      */

769     public synchronized void removeAllNotifications() {
770         
771         Object JavaDoc[] obj;
772         TimerAlarmClock JavaDoc alarmClock;
773
774     Enumeration JavaDoc e = timerTable.elements();
775         while (e.hasMoreElements()) {
776           
777             obj = (Object JavaDoc[])e.nextElement();
778           
779             // Stop the TimerAlarmClock.
780
//
781
alarmClock = (TimerAlarmClock JavaDoc)obj[ALARM_CLOCK_INDEX];
782 // if (alarmClock != null) {
783
// alarmClock.interrupt();
784
// try {
785
// // Wait until the thread die.
786
// //
787
// alarmClock.join();
788
// } catch (InterruptedException ex) {
789
// // Ignore...
790
// }
791
// Remove the reference on the TimerAlarmClock.
792
//
793
// }
794
alarmClock.cancel();
795             alarmClock = null;
796         }
797                 
798         // Remove all the timer notifications from the timer table.
799
//
800
if (isTraceOn()) {
801             trace("removeAllNotifications", "removing all timer notifications");
802         }
803         
804         timerTable.clear();
805         
806         if (isTraceOn()) {
807             trace("removeAllNotifications", "all timer notifications removed");
808         }
809         
810         // Reset the counterID.
811
//
812
counterID = 0;
813         
814         if (isTraceOn()) {
815             trace("removeAllNotifications", "timer notification counter ID resetted");
816         }
817     }
818