Source Code Cross Referenced for Timer.java in  » 6.0-JDK-Core » management » javax » management » timer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » management » javax.management.timer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001        /*
0002         * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004         *
0005         * This code is free software; you can redistribute it and/or modify it
0006         * under the terms of the GNU General Public License version 2 only, as
0007         * published by the Free Software Foundation.  Sun designates this
0008         * particular file as subject to the "Classpath" exception as provided
0009         * by Sun in the LICENSE file that accompanied this code.
0010         *
0011         * This code is distributed in the hope that it will be useful, but WITHOUT
0012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014         * version 2 for more details (a copy is included in the LICENSE file that
0015         * accompanied this code).
0016         *
0017         * You should have received a copy of the GNU General Public License version
0018         * 2 along with this work; if not, write to the Free Software Foundation,
0019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020         *
0021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022         * CA 95054 USA or visit www.sun.com if you need additional information or
0023         * have any questions.
0024         */
0025
0026        package javax.management.timer;
0027
0028        import static com.sun.jmx.defaults.JmxProperties.TIMER_LOGGER;
0029        import java.util.Date;
0030        import java.util.Hashtable;
0031        import java.util.Iterator;
0032        import java.util.Map;
0033        import java.util.Set;
0034        import java.util.TreeSet;
0035        import java.util.Vector;
0036        import java.util.logging.Level;
0037
0038        // jmx imports
0039        //
0040        import javax.management.InstanceNotFoundException;
0041        import javax.management.MBeanNotificationInfo;
0042        import javax.management.MBeanRegistration;
0043        import javax.management.MBeanServer;
0044        import javax.management.NotificationBroadcasterSupport;
0045        import javax.management.ObjectName;
0046
0047        /**
0048         *
0049         * Provides the implementation of the timer MBean.
0050         * The timer MBean sends out an alarm at a specified time
0051         * that wakes up all the listeners registered to receive timer notifications.
0052         * <P>
0053         *
0054         * This class manages a list of dated timer notifications.
0055         * A method allows users to add/remove as many notifications as required.
0056         * When a timer notification is emitted by the timer and becomes obsolete,
0057         * it is automatically removed from the list of timer notifications.
0058         * <BR>Additional timer notifications can be added into regularly repeating notifications.
0059         * <P>
0060         *
0061         * Note:
0062         * <OL>
0063         * <LI>When sending timer notifications, the timer updates the notification sequence number
0064         * irrespective of the notification type.
0065         * <LI>The timer service relies on the system date of the host where the <CODE>Timer</CODE> class is loaded.
0066         * Listeners may receive untimely notifications
0067         * if their host has a different system date.
0068         * To avoid such problems, synchronize the system date of all host machines where timing is needed.
0069         * <LI>The default behavior for periodic notifications is <i>fixed-delay execution</i>, as
0070         *     specified in {@link java.util.Timer}. In order to use <i>fixed-rate execution</i>, use the
0071         *     overloaded {@link #addNotification(String, String, Object, Date, long, long, boolean)} method.
0072         * <LI>Notification listeners are potentially all executed in the same
0073         * thread.  Therefore, they should execute rapidly to avoid holding up
0074         * other listeners or perturbing the regularity of fixed-delay
0075         * executions.  See {@link NotificationBroadcasterSupport}.
0076         * </OL>
0077         *
0078         * @since 1.5
0079         */
0080        public class Timer extends NotificationBroadcasterSupport implements 
0081                TimerMBean, MBeanRegistration {
0082
0083            /*
0084             * ------------------------------------------
0085             *  PUBLIC VARIABLES
0086             * ------------------------------------------
0087             */
0088
0089            /**
0090             * Number of milliseconds in one second.
0091             * Useful constant for the <CODE>addNotification</CODE> method.
0092             */
0093            public static final long ONE_SECOND = 1000;
0094
0095            /**
0096             * Number of milliseconds in one minute.
0097             * Useful constant for the <CODE>addNotification</CODE> method.
0098             */
0099            public static final long ONE_MINUTE = 60 * ONE_SECOND;
0100
0101            /**
0102             * Number of milliseconds in one hour.
0103             * Useful constant for the <CODE>addNotification</CODE> method.
0104             */
0105            public static final long ONE_HOUR = 60 * ONE_MINUTE;
0106
0107            /**
0108             * Number of milliseconds in one day.
0109             * Useful constant for the <CODE>addNotification</CODE> method.
0110             */
0111            public static final long ONE_DAY = 24 * ONE_HOUR;
0112
0113            /**
0114             * Number of milliseconds in one week.
0115             * Useful constant for the <CODE>addNotification</CODE> method.
0116             */
0117            public static final long ONE_WEEK = 7 * ONE_DAY;
0118
0119            /*
0120             * ------------------------------------------
0121             *  PRIVATE VARIABLES
0122             * ------------------------------------------
0123             */
0124
0125            /**
0126             * Table containing all the timer notifications of this timer,
0127             * with the associated date, period and number of occurrences.
0128             */
0129            private Map<Integer, Object[]> timerTable = new Hashtable<Integer, Object[]>();
0130
0131            /**
0132             * Past notifications sending on/off flag value.
0133             * This attribute is used to specify if the timer has to send past notifications after start.
0134             * <BR>The default value is set to <CODE>false</CODE>.
0135             */
0136            private boolean sendPastNotifications = false;
0137
0138            /**
0139             * Timer state.
0140             * The default value is set to <CODE>false</CODE>.
0141             */
0142            private transient boolean isActive = false;
0143
0144            /**
0145             * Timer sequence number.
0146             * The default value is set to 0.
0147             */
0148            private transient long sequenceNumber = 0;
0149
0150            // Flags needed to keep the indexes of the objects in the array.
0151            //
0152            private static final int TIMER_NOTIF_INDEX = 0;
0153            private static final int TIMER_DATE_INDEX = 1;
0154            private static final int TIMER_PERIOD_INDEX = 2;
0155            private static final int TIMER_NB_OCCUR_INDEX = 3;
0156            private static final int ALARM_CLOCK_INDEX = 4;
0157            private static final int FIXED_RATE_INDEX = 5;
0158
0159            /**
0160             * The notification counter ID.
0161             * Used to keep the max key value inserted into the timer table.
0162             */
0163            private int counterID = 0;
0164
0165            private java.util.Timer timer;
0166
0167            /*
0168             * ------------------------------------------
0169             *  CONSTRUCTORS
0170             * ------------------------------------------
0171             */
0172
0173            /**
0174             * Default constructor.
0175             */
0176            public Timer() {
0177            }
0178
0179            /*
0180             * ------------------------------------------
0181             *  PUBLIC METHODS
0182             * ------------------------------------------
0183             */
0184
0185            /**
0186             * Allows the timer MBean to perform any operations it needs before being registered
0187             * in the MBean server.
0188             * <P>
0189             * Not used in this context.
0190             *
0191             * @param server The MBean server in which the timer MBean will be registered.
0192             * @param name The object name of the timer MBean.
0193             *
0194             * @return The name of the timer MBean registered.
0195             *
0196             * @exception java.lang.Exception
0197             */
0198            public ObjectName preRegister(MBeanServer server, ObjectName name)
0199                    throws java.lang.Exception {
0200                return name;
0201            }
0202
0203            /**
0204             * Allows the timer MBean to perform any operations needed after having been
0205             * registered in the MBean server or after the registration has failed.
0206             * <P>
0207             * Not used in this context.
0208             */
0209            public void postRegister(Boolean registrationDone) {
0210            }
0211
0212            /**
0213             * Allows the timer MBean to perform any operations it needs before being unregistered
0214             * by the MBean server.
0215             * <P>
0216             * Stops the timer.
0217             *
0218             * @exception java.lang.Exception
0219             */
0220            public void preDeregister() throws java.lang.Exception {
0221
0222                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0223                        "preDeregister", "stop the timer");
0224
0225                // Stop the timer.
0226                //
0227                stop();
0228            }
0229
0230            /**
0231             * Allows the timer MBean to perform any operations needed after having been
0232             * unregistered by the MBean server.
0233             * <P>
0234             * Not used in this context.
0235             */
0236            public void postDeregister() {
0237            }
0238
0239            /*
0240             * This overrides the method in NotificationBroadcasterSupport.
0241             * Return the MBeanNotificationInfo[] array for this MBean.
0242             * The returned array has one element to indicate that the MBean
0243             * can emit TimerNotification.  The array of type strings
0244             * associated with this entry is a snapshot of the current types
0245             * that were given to addNotification.
0246             */
0247            public synchronized MBeanNotificationInfo[] getNotificationInfo() {
0248                Set<String> notifTypes = new TreeSet<String>();
0249                for (Iterator it = timerTable.values().iterator(); it.hasNext();) {
0250                    Object[] entry = (Object[]) it.next();
0251                    TimerNotification notif = (TimerNotification) entry[TIMER_NOTIF_INDEX];
0252                    notifTypes.add(notif.getType());
0253                }
0254                String[] notifTypesArray = notifTypes.toArray(new String[0]);
0255                return new MBeanNotificationInfo[] { new MBeanNotificationInfo(
0256                        notifTypesArray, TimerNotification.class.getName(),
0257                        "Notification sent by Timer MBean") };
0258            }
0259
0260            /**
0261             * Starts the timer.
0262             * <P>
0263             * If there is one or more timer notifications before the time in the list of notifications, the notification
0264             * is sent according to the <CODE>sendPastNotifications</CODE> flag and then, updated
0265             * according to its period and remaining number of occurrences.
0266             * If the timer notification date remains earlier than the current date, this notification is just removed
0267             * from the list of notifications.
0268             */
0269            public synchronized void start() {
0270
0271                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(), "start",
0272                        "starting the timer");
0273
0274                // Start the TimerAlarmClock.
0275                //
0276                if (isActive == false) {
0277
0278                    timer = new java.util.Timer();
0279
0280                    TimerAlarmClock alarmClock;
0281                    Date date;
0282
0283                    Date currentDate = new Date();
0284
0285                    // Send or not past notifications depending on the flag.
0286                    // Update the date and the number of occurrences of past notifications
0287                    // to make them later than the current date.
0288                    //
0289                    sendPastNotifications(currentDate, sendPastNotifications);
0290
0291                    // Update and start all the TimerAlarmClocks.
0292                    // Here, all the notifications in the timer table are later than the current date.
0293                    //
0294                    for (Object[] obj : timerTable.values()) {
0295
0296                        // Retrieve the date notification and the TimerAlarmClock.
0297                        //
0298                        date = (Date) obj[TIMER_DATE_INDEX];
0299
0300                        // Update all the TimerAlarmClock timeouts and start them.
0301                        //
0302                        boolean fixedRate = ((Boolean) obj[FIXED_RATE_INDEX])
0303                                .booleanValue();
0304                        if (fixedRate) {
0305                            alarmClock = new TimerAlarmClock(this , date);
0306                            obj[ALARM_CLOCK_INDEX] = (Object) alarmClock;
0307                            timer.schedule(alarmClock, alarmClock.next);
0308                        } else {
0309                            alarmClock = new TimerAlarmClock(this , (date
0310                                    .getTime() - currentDate.getTime()));
0311                            obj[ALARM_CLOCK_INDEX] = (Object) alarmClock;
0312                            timer.schedule(alarmClock, alarmClock.timeout);
0313                        }
0314                    }
0315
0316                    // Set the state to ON.
0317                    //
0318                    isActive = true;
0319
0320                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0321                            "start", "timer started");
0322                } else {
0323                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0324                            "start", "the timer is already activated");
0325                }
0326            }
0327
0328            /**
0329             * Stops the timer.
0330             */
0331            public synchronized void stop() {
0332
0333                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(), "stop",
0334                        "stopping the timer");
0335
0336                // Stop the TimerAlarmClock.
0337                //
0338                if (isActive == true) {
0339
0340                    TimerAlarmClock alarmClock;
0341
0342                    for (Object[] obj : timerTable.values()) {
0343
0344                        // Stop all the TimerAlarmClock.
0345                        //
0346                        alarmClock = (TimerAlarmClock) obj[ALARM_CLOCK_INDEX];
0347                        if (alarmClock != null) {
0348                            //                     alarmClock.interrupt();
0349                            //                     try {
0350                            //                         // Wait until the thread die.
0351                            //                         //
0352                            //                         alarmClock.join();
0353                            //                     } catch (InterruptedException ex) {
0354                            //                         // Ignore...
0355                            //                     }
0356                            //                     // Remove the reference on the TimerAlarmClock.
0357                            //                     //
0358
0359                            alarmClock.cancel();
0360                            alarmClock = null;
0361                        }
0362                    }
0363
0364                    timer.cancel();
0365
0366                    // Set the state to OFF.
0367                    //
0368                    isActive = false;
0369
0370                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0371                            "stop", "timer stopped");
0372                } else {
0373                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0374                            "stop", "the timer is already deactivated");
0375                }
0376            }
0377
0378            /**
0379             * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
0380             * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date,
0381             * period and number of occurrences.
0382             * <P>
0383             * If the timer notification to be inserted has a date that is before the current date,
0384             * the method behaves as if the specified date were the current date. <BR>
0385             * For once-off notifications, the notification is delivered immediately. <BR>
0386             * For periodic notifications, the first notification is delivered immediately and the
0387             * subsequent ones are spaced as specified by the period parameter.
0388             * <P>
0389             * Note that once the timer notification has been added into the list of notifications,
0390             * its associated date, period and number of occurrences cannot be updated.
0391             * <P>
0392             * In the case of a periodic notification, the value of parameter <i>fixedRate</i> is used to
0393             * specify the execution scheme, as specified in {@link java.util.Timer}.
0394             *
0395             * @param type The timer notification type.
0396             * @param message The timer notification detailed message.
0397             * @param userData The timer notification user data object.
0398             * @param date The date when the notification occurs.
0399             * @param period The period of the timer notification (in milliseconds).
0400             * @param nbOccurences The total number the timer notification will be emitted.
0401             * @param fixedRate If <code>true</code> and if the notification is periodic, the notification
0402             *                  is scheduled with a <i>fixed-rate</i> execution scheme. If
0403             *                  <code>false</code> and if the notification is periodic, the notification
0404             *                  is scheduled with a <i>fixed-delay</i> execution scheme. Ignored if the
0405             *                  notification is not periodic.
0406             *
0407             * @return The identifier of the new created timer notification.
0408             *
0409             * @exception java.lang.IllegalArgumentException The date is {@code null} or
0410             * the period or the number of occurrences is negative.
0411             *
0412             * @see #addNotification(String, String, Object, Date, long, long)
0413             */
0414            // NPCTE fix for bugId 4464388, esc 0,  MR, to be added after modification of jmx spec
0415            //  public synchronized Integer addNotification(String type, String message, Serializable userData,
0416            //                                                Date date, long period, long nbOccurences)
0417            // end of NPCTE fix for bugId 4464388
0418            public synchronized Integer addNotification(String type,
0419                    String message, Object userData, Date date, long period,
0420                    long nbOccurences, boolean fixedRate)
0421                    throws java.lang.IllegalArgumentException {
0422
0423                if (date == null) {
0424                    throw new java.lang.IllegalArgumentException(
0425                            "Timer notification date cannot be null.");
0426                }
0427
0428                // Check that all the timer notification attributes are valid.
0429                //
0430
0431                // Invalid timer period value exception:
0432                // Check that the period and the nbOccurences are POSITIVE VALUES.
0433                //
0434                if ((period < 0) || (nbOccurences < 0)) {
0435                    throw new java.lang.IllegalArgumentException(
0436                            "Negative values for the periodicity");
0437                }
0438
0439                Date currentDate = new Date();
0440
0441                // Update the date if it is before the current date.
0442                //
0443                if (currentDate.after(date)) {
0444
0445                    date.setTime(currentDate.getTime());
0446                    if (TIMER_LOGGER.isLoggable(Level.FINER)) {
0447                        TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0448                                "addNotification",
0449                                "update timer notification to add with:"
0450                                        + "\n\tNotification date = " + date);
0451                    }
0452                }
0453
0454                // Create and add the timer notification into the timer table.
0455                //
0456                Integer notifID = null;
0457                notifID = new Integer(++counterID);
0458
0459                // The sequenceNumber and the timeStamp attributes are updated
0460                // when the notification is emitted by the timer.
0461                //
0462                TimerNotification notif = new TimerNotification(type, this , 0,
0463                        0, message, notifID);
0464                notif.setUserData(userData);
0465
0466                Object[] obj = new Object[6];
0467
0468                TimerAlarmClock alarmClock;
0469                if (fixedRate) {
0470                    alarmClock = new TimerAlarmClock(this , date);
0471                } else {
0472                    alarmClock = new TimerAlarmClock(this ,
0473                            (date.getTime() - currentDate.getTime()));
0474                }
0475
0476                // Fix bug 00417.B
0477                // The date registered into the timer is a clone from the date parameter.
0478                //
0479                Date d = new Date(date.getTime());
0480
0481                obj[TIMER_NOTIF_INDEX] = (Object) notif;
0482                obj[TIMER_DATE_INDEX] = (Object) d;
0483                obj[TIMER_PERIOD_INDEX] = (Object) new Long(period);
0484                obj[TIMER_NB_OCCUR_INDEX] = (Object) new Long(nbOccurences);
0485                obj[ALARM_CLOCK_INDEX] = (Object) alarmClock;
0486                obj[FIXED_RATE_INDEX] = Boolean.valueOf(fixedRate);
0487
0488                if (TIMER_LOGGER.isLoggable(Level.FINER)) {
0489                    StringBuilder strb = new StringBuilder()
0490                            .append("adding timer notification:\n\t")
0491                            .append("Notification source = ")
0492                            .append(notif.getSource())
0493                            .append("\n\tNotification type = ")
0494                            .append(notif.getType())
0495                            .append("\n\tNotification ID = ")
0496                            .append(notifID)
0497                            .append("\n\tNotification date = ")
0498                            .append(d)
0499                            .append("\n\tNotification period = ")
0500                            .append(period)
0501                            .append("\n\tNotification nb of occurrences = ")
0502                            .append(nbOccurences)
0503                            .append(
0504                                    "\n\tNotification executes at fixed rate = ")
0505                            .append(fixedRate);
0506                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0507                            "addNotification", strb.toString());
0508                }
0509
0510                timerTable.put(notifID, obj);
0511
0512                // Update and start the TimerAlarmClock.
0513                //
0514                if (isActive == true) {
0515                    if (fixedRate) {
0516                        timer.schedule(alarmClock, alarmClock.next);
0517                    } else {
0518                        timer.schedule(alarmClock, alarmClock.timeout);
0519                    }
0520                }
0521
0522                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0523                        "addNotification", "timer notification added");
0524                return notifID;
0525            }
0526
0527            /**
0528             * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
0529             * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date,
0530             * period and number of occurrences.
0531             * <P>
0532             * If the timer notification to be inserted has a date that is before the current date,
0533             * the method behaves as if the specified date were the current date. <BR>
0534             * For once-off notifications, the notification is delivered immediately. <BR>
0535             * For periodic notifications, the first notification is delivered immediately and the
0536             * subsequent ones are spaced as specified by the period parameter.
0537             * <P>
0538             * Note that once the timer notification has been added into the list of notifications,
0539             * its associated date, period and number of occurrences cannot be updated.
0540             * <P>
0541             * In the case of a periodic notification, uses a <i>fixed-delay</i> execution scheme, as specified in
0542             * {@link java.util.Timer}. In order to use a <i>fixed-rate</i> execution scheme, use
0543             * {@link #addNotification(String, String, Object, Date, long, long, boolean)} instead.
0544             *
0545             * @param type The timer notification type.
0546             * @param message The timer notification detailed message.
0547             * @param userData The timer notification user data object.
0548             * @param date The date when the notification occurs.
0549             * @param period The period of the timer notification (in milliseconds).
0550             * @param nbOccurences The total number the timer notification will be emitted.
0551             *
0552             * @return The identifier of the new created timer notification.
0553             *
0554             * @exception java.lang.IllegalArgumentException The date is {@code null} or
0555             * the period or the number of occurrences is negative.
0556             *
0557             * @see #addNotification(String, String, Object, Date, long, long, boolean)
0558             */
0559            // NPCTE fix for bugId 4464388, esc 0,  MR , to be added after modification of jmx spec
0560            //  public synchronized Integer addNotification(String type, String message, Serializable userData,
0561            //                                              Date date, long period)
0562            // end of NPCTE fix for bugId 4464388 */
0563            public synchronized Integer addNotification(String type,
0564                    String message, Object userData, Date date, long period,
0565                    long nbOccurences)
0566                    throws java.lang.IllegalArgumentException {
0567
0568                return addNotification(type, message, userData, date, period,
0569                        nbOccurences, false);
0570            }
0571
0572            /**
0573             * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
0574             * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date
0575             * and period and a null number of occurrences.
0576             * <P>
0577             * The timer notification will repeat continuously using the timer period using a <i>fixed-delay</i>
0578             * execution scheme, as specified in {@link java.util.Timer}. In order to use a <i>fixed-rate</i>
0579             * execution scheme, use {@link #addNotification(String, String, Object, Date, long, long,
0580             * boolean)} instead.
0581             * <P>
0582             * If the timer notification to be inserted has a date that is before the current date,
0583             * the method behaves as if the specified date were the current date. The
0584             * first notification is delivered immediately and the subsequent ones are
0585             * spaced as specified by the period parameter.
0586             *
0587             * @param type The timer notification type.
0588             * @param message The timer notification detailed message.
0589             * @param userData The timer notification user data object.
0590             * @param date The date when the notification occurs.
0591             * @param period The period of the timer notification (in milliseconds).
0592             *
0593             * @return The identifier of the new created timer notification.
0594             *
0595             * @exception java.lang.IllegalArgumentException The date is {@code null} or
0596             * the period is negative.
0597             */
0598            // NPCTE fix for bugId 4464388, esc 0,  MR , to be added after modification of jmx spec
0599            //  public synchronized Integer addNotification(String type, String message, Serializable userData,
0600            //                                              Date date, long period)
0601            // end of NPCTE fix for bugId 4464388 */
0602            public synchronized Integer addNotification(String type,
0603                    String message, Object userData, Date date, long period)
0604                    throws java.lang.IllegalArgumentException {
0605
0606                return (addNotification(type, message, userData, date, period,
0607                        0));
0608            }
0609
0610            /**
0611             * Creates a new timer notification with the specified <CODE>type</CODE>, <CODE>message</CODE>
0612             * and <CODE>userData</CODE> and inserts it into the list of notifications with a given date
0613             * and a null period and number of occurrences.
0614             * <P>
0615             * The timer notification will be handled once at the specified date.
0616             * <P>
0617             * If the timer notification to be inserted has a date that is before the current date,
0618             * the method behaves as if the specified date were the current date and the
0619             * notification is delivered immediately.
0620             *
0621             * @param type The timer notification type.
0622             * @param message The timer notification detailed message.
0623             * @param userData The timer notification user data object.
0624             * @param date The date when the notification occurs.
0625             *
0626             * @return The identifier of the new created timer notification.
0627             *
0628             * @exception java.lang.IllegalArgumentException The date is {@code null}.
0629             */
0630            // NPCTE fix for bugId 4464388, esc 0,  MR, to be added after modification of jmx spec
0631            //  public synchronized Integer addNotification(String type, String message, Serializable userData, Date date)
0632            //      throws java.lang.IllegalArgumentException {
0633            // end of NPCTE fix for bugId 4464388
0634            public synchronized Integer addNotification(String type,
0635                    String message, Object userData, Date date)
0636                    throws java.lang.IllegalArgumentException {
0637
0638                return (addNotification(type, message, userData, date, 0, 0));
0639            }
0640
0641            /**
0642             * Removes the timer notification corresponding to the specified identifier from the list of notifications.
0643             *
0644             * @param id The timer notification identifier.
0645             *
0646             * @exception InstanceNotFoundException The specified identifier does not correspond to any timer notification
0647             * in the list of notifications of this timer MBean.
0648             */
0649            public synchronized void removeNotification(Integer id)
0650                    throws InstanceNotFoundException {
0651
0652                // Check that the notification to remove is effectively in the timer table.
0653                //
0654                if (timerTable.containsKey(id) == false) {
0655                    throw new InstanceNotFoundException(
0656                            "Timer notification to remove not in the list of notifications");
0657                }
0658
0659                // Stop the TimerAlarmClock.
0660                //
0661                Object[] obj = timerTable.get(id);
0662                TimerAlarmClock alarmClock = (TimerAlarmClock) obj[ALARM_CLOCK_INDEX];
0663                if (alarmClock != null) {
0664                    //             alarmClock.interrupt();
0665                    //             try {
0666                    //                 // Wait until the thread die.
0667                    //                 //
0668                    //                 alarmClock.join();
0669                    //             } catch (InterruptedException e) {
0670                    //                 // Ignore...
0671                    //             }
0672                    //             // Remove the reference on the TimerAlarmClock.
0673                    //             //
0674                    alarmClock.cancel();
0675                    alarmClock = null;
0676                }
0677
0678                // Remove the timer notification from the timer table.
0679                //
0680                if (TIMER_LOGGER.isLoggable(Level.FINER)) {
0681                    StringBuilder strb = new StringBuilder()
0682                            .append("removing timer notification:")
0683                            .append("\n\tNotification source = ")
0684                            .append(
0685                                    ((TimerNotification) obj[TIMER_NOTIF_INDEX])
0686                                            .getSource())
0687                            .append("\n\tNotification type = ")
0688                            .append(
0689                                    ((TimerNotification) obj[TIMER_NOTIF_INDEX])
0690                                            .getType())
0691                            .append("\n\tNotification ID = ")
0692                            .append(
0693                                    ((TimerNotification) obj[TIMER_NOTIF_INDEX])
0694                                            .getNotificationID())
0695                            .append("\n\tNotification date = ")
0696                            .append(obj[TIMER_DATE_INDEX])
0697                            .append("\n\tNotification period = ")
0698                            .append(obj[TIMER_PERIOD_INDEX])
0699                            .append("\n\tNotification nb of occurrences = ")
0700                            .append(obj[TIMER_NB_OCCUR_INDEX])
0701                            .append(
0702                                    "\n\tNotification executes at fixed rate = ")
0703                            .append(obj[FIXED_RATE_INDEX]);
0704                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0705                            "removeNotification", strb.toString());
0706                }
0707
0708                timerTable.remove(id);
0709
0710                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0711                        "removeNotification", "timer notification removed");
0712            }
0713
0714            /**
0715             * Removes all the timer notifications corresponding to the specified type from the list of notifications.
0716             *
0717             * @param type The timer notification type.
0718             *
0719             * @exception InstanceNotFoundException The specified type does not correspond to any timer notification
0720             * in the list of notifications of this timer MBean.
0721             */
0722            public synchronized void removeNotifications(String type)
0723                    throws InstanceNotFoundException {
0724
0725                Vector<Integer> v = getNotificationIDs(type);
0726
0727                if (v.isEmpty())
0728                    throw new InstanceNotFoundException(
0729                            "Timer notifications to remove not in the list of notifications");
0730
0731                for (Integer i : v)
0732                    removeNotification(i);
0733            }
0734
0735            /**
0736             * Removes all the timer notifications from the list of notifications
0737             * and resets the counter used to update the timer notification identifiers.
0738             */
0739            public synchronized void removeAllNotifications() {
0740
0741                TimerAlarmClock alarmClock;
0742
0743                for (Object[] obj : timerTable.values()) {
0744
0745                    // Stop the TimerAlarmClock.
0746                    //
0747                    alarmClock = (TimerAlarmClock) obj[ALARM_CLOCK_INDEX];
0748                    //             if (alarmClock != null) {
0749                    //                 alarmClock.interrupt();
0750                    //                 try {
0751                    //                     // Wait until the thread die.
0752                    //                     //
0753                    //                     alarmClock.join();
0754                    //                 } catch (InterruptedException ex) {
0755                    //                     // Ignore...
0756                    //                 }
0757                    // Remove the reference on the TimerAlarmClock.
0758                    //
0759                    // 	       }
0760                    alarmClock.cancel();
0761                    alarmClock = null;
0762                }
0763
0764                // Remove all the timer notifications from the timer table.
0765                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0766                        "removeAllNotifications",
0767                        "removing all timer notifications");
0768
0769                timerTable.clear();
0770
0771                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0772                        "removeAllNotifications",
0773                        "all timer notifications removed");
0774                // Reset the counterID.
0775                //
0776                counterID = 0;
0777
0778                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
0779                        "removeAllNotifications",
0780                        "timer notification counter ID reset");
0781            }
0782
0783            // GETTERS AND SETTERS
0784            //--------------------
0785
0786            /**
0787             * Gets the number of timer notifications registered into the list of notifications.
0788             *
0789             * @return The number of timer notifications.
0790             */
0791            public int getNbNotifications() {
0792                return timerTable.size();
0793            }
0794
0795            /**
0796             * Gets all timer notification identifiers registered into the list of notifications.
0797             *
0798             * @return A vector of <CODE>Integer</CODE> objects containing all the timer notification identifiers.
0799             * <BR>The vector is empty if there is no timer notification registered for this timer MBean.
0800             */
0801            public synchronized Vector<Integer> getAllNotificationIDs() {
0802                return new Vector<Integer>(timerTable.keySet());
0803            }
0804
0805            /**
0806             * Gets all the identifiers of timer notifications corresponding to the specified type.
0807             *
0808             * @param type The timer notification type.
0809             *
0810             * @return A vector of <CODE>Integer</CODE> objects containing all the identifiers of
0811             * timer notifications with the specified <CODE>type</CODE>.
0812             * <BR>The vector is empty if there is no timer notifications registered for this timer MBean
0813             * with the specified <CODE>type</CODE>.
0814             */
0815            public synchronized Vector<Integer> getNotificationIDs(String type) {
0816
0817                String s;
0818
0819                Vector<Integer> v = new Vector<Integer>();
0820
0821                for (Map.Entry<Integer, Object[]> entry : timerTable.entrySet()) {
0822                    Object[] obj = entry.getValue();
0823                    s = ((TimerNotification) obj[TIMER_NOTIF_INDEX]).getType();
0824                    if ((type == null) ? s == null : type.equals(s))
0825                        v.addElement(entry.getKey());
0826                }
0827                return v;
0828            }
0829
0830            // 5089997: return is Vector<Integer> not Vector<TimerNotification>
0831
0832            /**
0833             * Gets the timer notification type corresponding to the specified identifier.
0834             *
0835             * @param id The timer notification identifier.
0836             *
0837             * @return The timer notification type or null if the identifier is not mapped to any
0838             * timer notification registered for this timer MBean.
0839             */
0840            public String getNotificationType(Integer id) {
0841
0842                Object[] obj = timerTable.get(id);
0843                if (obj != null) {
0844                    return (((TimerNotification) obj[TIMER_NOTIF_INDEX])
0845                            .getType());
0846                }
0847                return null;
0848            }
0849
0850            /**
0851             * Gets the timer notification detailed message corresponding to the specified identifier.
0852             *
0853             * @param id The timer notification identifier.
0854             *
0855             * @return The timer notification detailed message or null if the identifier is not mapped to any
0856             * timer notification registered for this timer MBean.
0857             */
0858            public String getNotificationMessage(Integer id) {
0859
0860                Object[] obj = timerTable.get(id);
0861                if (obj != null) {
0862                    return (((TimerNotification) obj[TIMER_NOTIF_INDEX])
0863                            .getMessage());
0864                }
0865                return null;
0866            }
0867
0868            /**
0869             * Gets the timer notification user data object corresponding to the specified identifier.
0870             *
0871             * @param id The timer notification identifier.
0872             *
0873             * @return The timer notification user data object or null if the identifier is not mapped to any
0874             * timer notification registered for this timer MBean.
0875             */
0876            // NPCTE fix for bugId 4464388, esc 0, MR, 03 sept 2001, to be added after modification of jmx spec
0877            //public Serializable getNotificationUserData(Integer id) {
0878            // end of NPCTE fix for bugId 4464388
0879            public Object getNotificationUserData(Integer id) {
0880                Object[] obj = timerTable.get(id);
0881                if (obj != null) {
0882                    return (((TimerNotification) obj[TIMER_NOTIF_INDEX])
0883                            .getUserData());
0884                }
0885                return null;
0886            }
0887
0888            /**
0889             * Gets a copy of the date associated to a timer notification.
0890             *
0891             * @param id The timer notification identifier.
0892             *
0893             * @return A copy of the date or null if the identifier is not mapped to any
0894             * timer notification registered for this timer MBean.
0895             */
0896            public Date getDate(Integer id) {
0897
0898                Object[] obj = timerTable.get(id);
0899                if (obj != null) {
0900                    Date date = (Date) obj[TIMER_DATE_INDEX];
0901                    return (new Date(date.getTime()));
0902                }
0903                return null;
0904            }
0905
0906            /**
0907             * Gets a copy of the period (in milliseconds) associated to a timer notification.
0908             *
0909             * @param id The timer notification identifier.
0910             *
0911             * @return A copy of the period or null if the identifier is not mapped to any
0912             * timer notification registered for this timer MBean.
0913             */
0914            public Long getPeriod(Integer id) {
0915
0916                Object[] obj = timerTable.get(id);
0917                if (obj != null) {
0918                    Long period = (Long) obj[TIMER_PERIOD_INDEX];
0919                    return (new Long(period.longValue()));
0920                }
0921                return null;
0922            }
0923
0924            /**
0925             * Gets a copy of the remaining number of occurrences associated to a timer notification.
0926             *
0927             * @param id The timer notification identifier.
0928             *
0929             * @return A copy of the remaining number of occurrences or null if the identifier is not mapped to any
0930             * timer notification registered for this timer MBean.
0931             */
0932            public Long getNbOccurences(Integer id) {
0933
0934                Object[] obj = timerTable.get(id);
0935                if (obj != null) {
0936                    Long nbOccurences = (Long) obj[TIMER_NB_OCCUR_INDEX];
0937                    return (new Long(nbOccurences.longValue()));
0938                }
0939                return null;
0940            }
0941
0942            /**
0943             * Gets a copy of the flag indicating whether a periodic notification is
0944             * executed at <i>fixed-delay</i> or at <i>fixed-rate</i>.
0945             *
0946             * @param id The timer notification identifier.
0947             *
0948             * @return A copy of the flag indicating whether a periodic notification is
0949             *         executed at <i>fixed-delay</i> or at <i>fixed-rate</i>.
0950             */
0951            public Boolean getFixedRate(Integer id) {
0952
0953                Object[] obj = timerTable.get(id);
0954                if (obj != null) {
0955                    Boolean fixedRate = (Boolean) obj[FIXED_RATE_INDEX];
0956                    return (Boolean.valueOf(fixedRate.booleanValue()));
0957                }
0958                return null;
0959            }
0960
0961            /**
0962             * Gets the flag indicating whether or not the timer sends past notifications.
0963             * <BR>The default value of the past notifications sending on/off flag is <CODE>false</CODE>.
0964             *
0965             * @return The past notifications sending on/off flag value.
0966             *
0967             * @see #setSendPastNotifications
0968             */
0969            public boolean getSendPastNotifications() {
0970                return sendPastNotifications;
0971            }
0972
0973            /**
0974             * Sets the flag indicating whether the timer sends past notifications or not.
0975             * <BR>The default value of the past notifications sending on/off flag is <CODE>false</CODE>.
0976             *
0977             * @param value The past notifications sending on/off flag value.
0978             *
0979             * @see #getSendPastNotifications
0980             */
0981            public void setSendPastNotifications(boolean value) {
0982                sendPastNotifications = value;
0983            }
0984
0985            /**
0986             * Tests whether the timer MBean is active.
0987             * A timer MBean is marked active when the {@link #start start} method is called.
0988             * It becomes inactive when the {@link #stop stop} method is called.
0989             * <BR>The default value of the active on/off flag is <CODE>false</CODE>.
0990             *
0991             * @return <CODE>true</CODE> if the timer MBean is active, <CODE>false</CODE> otherwise.
0992             */
0993            public boolean isActive() {
0994                return isActive;
0995            }
0996
0997            /**
0998             * Tests whether the list of timer notifications is empty.
0999             *
1000             * @return <CODE>true</CODE> if the list of timer notifications is empty, <CODE>false</CODE> otherwise.
1001             */
1002            public boolean isEmpty() {
1003                return (timerTable.isEmpty());
1004            }
1005
1006            /*
1007             * ------------------------------------------
1008             *  PRIVATE METHODS
1009             * ------------------------------------------
1010             */
1011
1012            /**
1013             * Sends or not past notifications depending on the specified flag.
1014             *
1015             * @param currentDate The current date.
1016             * @param currentFlag The flag indicating if past notifications must be sent or not.
1017             */
1018            private synchronized void sendPastNotifications(Date currentDate,
1019                    boolean currentFlag) {
1020
1021                TimerNotification notif;
1022                Integer notifID;
1023                Date date;
1024
1025                for (Object[] obj : timerTable.values()) {
1026
1027                    // Retrieve the timer notification and the date notification.
1028                    //
1029                    notif = (TimerNotification) obj[TIMER_NOTIF_INDEX];
1030                    notifID = notif.getNotificationID();
1031                    date = (Date) obj[TIMER_DATE_INDEX];
1032
1033                    // Update the timer notification while:
1034                    //  - the timer notification date is earlier than the current date
1035                    //  - the timer notification has not been removed from the timer table.
1036                    //
1037                    while ((currentDate.after(date))
1038                            && (timerTable.containsKey(notifID))) {
1039
1040                        if (currentFlag == true) {
1041                            if (TIMER_LOGGER.isLoggable(Level.FINER)) {
1042                                StringBuilder strb = new StringBuilder()
1043                                        .append(
1044                                                "sending past timer notification:")
1045                                        .append("\n\tNotification source = ")
1046                                        .append(notif.getSource())
1047                                        .append("\n\tNotification type = ")
1048                                        .append(notif.getType())
1049                                        .append("\n\tNotification ID = ")
1050                                        .append(notif.getNotificationID())
1051                                        .append("\n\tNotification date = ")
1052                                        .append(date)
1053                                        .append("\n\tNotification period = ")
1054                                        .append(obj[TIMER_PERIOD_INDEX])
1055                                        .append(
1056                                                "\n\tNotification nb of occurrences = ")
1057                                        .append(obj[TIMER_NB_OCCUR_INDEX])
1058                                        .append(
1059                                                "\n\tNotification executes at fixed rate = ")
1060                                        .append(obj[FIXED_RATE_INDEX]);
1061                                TIMER_LOGGER.logp(Level.FINER, Timer.class
1062                                        .getName(), "sendPastNotifications",
1063                                        strb.toString());
1064                            }
1065                            sendNotification(date, notif);
1066
1067                            TIMER_LOGGER.logp(Level.FINER, Timer.class
1068                                    .getName(), "sendPastNotifications",
1069                                    "past timer notification sent");
1070                        }
1071
1072                        // Update the date and the number of occurrences of the timer notification.
1073                        //
1074                        updateTimerTable(notif.getNotificationID());
1075                    }
1076                }
1077            }
1078
1079            /**
1080             * If the timer notification is not periodic, it is removed from the list of notifications.
1081             * <P>
1082             * If the timer period of the timer notification has a non null periodicity,
1083             * the date of the timer notification is updated by adding the periodicity.
1084             * The associated TimerAlarmClock is updated by setting its timeout to the period value.
1085             * <P>
1086             * If the timer period has a defined number of occurrences, the timer
1087             * notification is updated if the number of occurrences has not yet been reached.
1088             * Otherwise it is removed from the list of notifications.
1089             *
1090             * @param notifID The timer notification identifier to update.
1091             */
1092            private synchronized void updateTimerTable(Integer notifID) {
1093
1094                // Retrieve the timer notification and the TimerAlarmClock.
1095                //
1096                Object[] obj = timerTable.get(notifID);
1097                Date date = (Date) obj[TIMER_DATE_INDEX];
1098                Long period = (Long) obj[TIMER_PERIOD_INDEX];
1099                Long nbOccurences = (Long) obj[TIMER_NB_OCCUR_INDEX];
1100                Boolean fixedRate = (Boolean) obj[FIXED_RATE_INDEX];
1101                TimerAlarmClock alarmClock = (TimerAlarmClock) obj[ALARM_CLOCK_INDEX];
1102
1103                if (period.longValue() != 0) {
1104
1105                    // Update the date and the number of occurrences of the timer notification
1106                    // and the TimerAlarmClock time out.
1107                    // NOTES :
1108                    //   nbOccurences = 0 notifies an infinite periodicity.
1109                    //   nbOccurences = 1 notifies a finite periodicity that has reached its end.
1110                    //   nbOccurences > 1 notifies a finite periodicity that has not yet reached its end.
1111                    //
1112                    if ((nbOccurences.longValue() == 0)
1113                            || (nbOccurences.longValue() > 1)) {
1114
1115                        date.setTime(date.getTime() + period.longValue());
1116                        obj[TIMER_NB_OCCUR_INDEX] = new Long(java.lang.Math
1117                                .max(0L, (nbOccurences.longValue() - 1)));
1118                        nbOccurences = (Long) obj[TIMER_NB_OCCUR_INDEX];
1119
1120                        if (isActive == true) {
1121                            if (fixedRate.booleanValue()) {
1122                                alarmClock = new TimerAlarmClock(this , date);
1123                                obj[ALARM_CLOCK_INDEX] = (Object) alarmClock;
1124                                timer.schedule(alarmClock, alarmClock.next);
1125                            } else {
1126                                alarmClock = new TimerAlarmClock(this , period
1127                                        .longValue());
1128                                obj[ALARM_CLOCK_INDEX] = (Object) alarmClock;
1129                                timer.schedule(alarmClock, alarmClock.timeout);
1130                            }
1131                        }
1132                        if (TIMER_LOGGER.isLoggable(Level.FINER)) {
1133                            TimerNotification notif = (TimerNotification) obj[TIMER_NOTIF_INDEX];
1134                            StringBuilder strb = new StringBuilder()
1135                                    .append("update timer notification with:")
1136                                    .append("\n\tNotification source = ")
1137                                    .append(notif.getSource())
1138                                    .append("\n\tNotification type = ")
1139                                    .append(notif.getType())
1140                                    .append("\n\tNotification ID = ")
1141                                    .append(notifID)
1142                                    .append("\n\tNotification date = ")
1143                                    .append(date)
1144                                    .append("\n\tNotification period = ")
1145                                    .append(period)
1146                                    .append(
1147                                            "\n\tNotification nb of occurrences = ")
1148                                    .append(nbOccurences)
1149                                    .append(
1150                                            "\n\tNotification executes at fixed rate = ")
1151                                    .append(fixedRate);
1152                            TIMER_LOGGER.logp(Level.FINER, Timer.class
1153                                    .getName(), "updateTimerTable", strb
1154                                    .toString());
1155                        }
1156                    } else {
1157                        if (alarmClock != null) {
1158                            //                     alarmClock.interrupt();
1159                            //                     try {
1160                            //                         // Wait until the thread die.
1161                            //                         //
1162                            //                         alarmClock.join();
1163                            //                     } catch (InterruptedException e) {
1164                            //                         // Ignore...
1165                            //                     }
1166                            alarmClock.cancel();
1167                            // Remove the reference on the TimerAlarmClock.
1168                            //
1169                            alarmClock = null;
1170                        }
1171                        timerTable.remove(notifID);
1172                    }
1173                } else {
1174                    if (alarmClock != null) {
1175                        //                 alarmClock.interrupt();
1176                        //                 try {
1177                        //                     // Wait until the thread die.
1178                        //                     //
1179                        //                     alarmClock.join();
1180                        //                 } catch (InterruptedException e) {
1181                        //                     // Ignore...
1182                        //                 }
1183
1184                        alarmClock.cancel();
1185
1186                        // Remove the reference on the TimerAlarmClock.
1187                        //
1188                        alarmClock = null;
1189                    }
1190                    timerTable.remove(notifID);
1191                }
1192            }
1193
1194            /*
1195             * ------------------------------------------
1196             *  PACKAGE METHODS
1197             * ------------------------------------------
1198             */
1199
1200            /**
1201             * This method is called by the timer each time
1202             * the TimerAlarmClock has exceeded its timeout.
1203             *
1204             * @param notification The TimerAlarmClock notification.
1205             */
1206            @SuppressWarnings("deprecation")
1207            void notifyAlarmClock(TimerAlarmClockNotification notification) {
1208
1209                TimerNotification timerNotification = null;
1210                Date timerDate = null;
1211
1212                // Retrieve the timer notification associated to the alarm-clock.
1213                //
1214                TimerAlarmClock alarmClock = (TimerAlarmClock) notification
1215                        .getSource();
1216
1217                for (Object[] obj : timerTable.values()) {
1218                    if (obj[ALARM_CLOCK_INDEX] == alarmClock) {
1219                        timerNotification = (TimerNotification) obj[TIMER_NOTIF_INDEX];
1220                        timerDate = (Date) obj[TIMER_DATE_INDEX];
1221                        break;
1222                    }
1223                }
1224
1225                // Notify the timer.
1226                //
1227                sendNotification(timerDate, timerNotification);
1228
1229                // Update the notification and the TimerAlarmClock timeout.
1230                //
1231                updateTimerTable(timerNotification.getNotificationID());
1232            }
1233
1234            /**
1235             * This method is used by the timer MBean to update and send a timer
1236             * notification to all the listeners registered for this kind of notification.
1237             *
1238             * @param timeStamp The notification emission date.
1239             * @param notification The timer notification to send.
1240             */
1241            void sendNotification(Date timeStamp, TimerNotification notification) {
1242
1243                if (TIMER_LOGGER.isLoggable(Level.FINER)) {
1244                    StringBuilder strb = new StringBuilder().append(
1245                            "sending timer notification:").append(
1246                            "\n\tNotification source = ").append(
1247                            notification.getSource()).append(
1248                            "\n\tNotification type = ").append(
1249                            notification.getType()).append(
1250                            "\n\tNotification ID = ").append(
1251                            notification.getNotificationID()).append(
1252                            "\n\tNotification date = ").append(timeStamp);
1253                    TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
1254                            "sendNotification", strb.toString());
1255                }
1256                long curSeqNumber;
1257                synchronized (this ) {
1258                    sequenceNumber = sequenceNumber + 1;
1259                    curSeqNumber = sequenceNumber;
1260                }
1261                synchronized (notification) {
1262                    notification.setTimeStamp(timeStamp.getTime());
1263                    notification.setSequenceNumber(curSeqNumber);
1264                    this .sendNotification((TimerNotification) notification
1265                            .cloneTimerNotification());
1266                }
1267
1268                TIMER_LOGGER.logp(Level.FINER, Timer.class.getName(),
1269                        "sendNotification", "timer notification sent");
1270            }
1271        }
1272
1273        /**
1274         * TimerAlarmClock inner class:
1275         * This class provides a simple implementation of an alarm clock MBean.
1276         * The aim of this MBean is to set up an alarm which wakes up the timer every timeout (fixed-delay)
1277         * or at the specified date (fixed-rate).
1278         */
1279
1280        class TimerAlarmClock extends java.util.TimerTask {
1281
1282            Timer listener = null;
1283            long timeout = 10000;
1284            Date next = null;
1285
1286            /*
1287             * ------------------------------------------
1288             *  CONSTRUCTORS
1289             * ------------------------------------------
1290             */
1291
1292            public TimerAlarmClock(Timer listener, long timeout) {
1293                this .listener = listener;
1294                this .timeout = Math.max(0L, timeout);
1295            }
1296
1297            public TimerAlarmClock(Timer listener, Date next) {
1298                this .listener = listener;
1299                this .next = next;
1300            }
1301
1302            /*
1303             * ------------------------------------------
1304             *  PUBLIC METHODS
1305             * ------------------------------------------
1306             */
1307
1308            /**
1309             * This method is called by the timer when it is started.
1310             */
1311            public void run() {
1312
1313                try {
1314                    //this.sleep(timeout);
1315                    TimerAlarmClockNotification notif = new TimerAlarmClockNotification(
1316                            this );
1317                    listener.notifyAlarmClock(notif);
1318                } catch (Exception e) {
1319                    TIMER_LOGGER
1320                            .logp(
1321                                    Level.FINEST,
1322                                    Timer.class.getName(),
1323                                    "run",
1324                                    "Got unexpected exception when sending a notification",
1325                                    e);
1326                }
1327            }
1328        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.