KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > monitor > PeriodicMonitor


1 package javax.management.monitor;
2 //java imports
3
//
4
import java.util.Date JavaDoc;
5 import java.util.Timer JavaDoc;
6 import java.util.TimerTask JavaDoc;
7
8 // jmx imports
9
//
10
import javax.management.ObjectName JavaDoc;
11 //import javax.management.MBeanNotificationInfo;
12
import javax.management.AttributeNotFoundException JavaDoc;
13 import javax.management.InstanceNotFoundException JavaDoc;
14 import javax.management.MBeanException JavaDoc;
15 import javax.management.ReflectionException JavaDoc;
16
17 /**
18  * Defines a monitor MBean designed to observe periodically the values of an attribute
19  *
20  * @version 0.1
21  */

22 public class PeriodicMonitor extends Monitor JavaDoc implements PeriodicMonitorMBean JavaDoc {
23     
24     /**
25      * Notification type denoting the observed attribute sample value.
26      * This notification is only fired by periodic monitors.
27      * <BR>The value of this notification type is <CODE>jmx.newMonitor.periodic</CODE>.
28      */

29     public static final String JavaDoc PERIODIC_SAMPLING = new String JavaDoc("jmx.monitor.periodic");
30
31     /*
32      * ------------------------------------------
33      * PRIVATE VARIABLES
34      * ------------------------------------------
35      */

36     /*private final static String[] types = {MonitorNotification.RUNTIME_ERROR,
37             MonitorNotification.OBSERVED_OBJECT_ERROR,
38             MonitorNotification.OBSERVED_ATTRIBUTE_ERROR,
39             MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
40             PERIODIC_SAMPLING}; // !!!
41     private final static MBeanNotificationInfo[] notifsInfo = {new MBeanNotificationInfo(
42             types, "javax.management.monitor.MonitorNotification",
43             "Notifications sent by the PeriodicMonitor MBean")};*/

44     
45     /**
46      * Derived gauges. <BR>
47      * Each element in this array corresponds to an observed object in the
48      * list.
49      */

50     private transient Object JavaDoc derivedGauge[] = new Object JavaDoc[capacityIncrement];
51
52     /**
53      * Derived gauge timestamps. <BR>
54      * Each element in this array corresponds to an observed object in the
55      * list.
56      */

57     private transient long derivedGaugeTimestamp[] = new long[capacityIncrement];
58
59     /**
60      * Timer.
61      */

62     private transient Timer JavaDoc timer = null;
63
64     /*
65      * ------------------------------------------
66      * PUBLIC METHODS
67      * ------------------------------------------
68      */

69
70     /**
71      * Starts the periodic monitor.
72      */

73     public synchronized void start() {
74         if (!isActive()) {
75             isActive = true;
76             // Start the AlarmClock.
77
timer = new Timer JavaDoc();
78             timer.schedule(new PeriodicAlarmClock(this),
79                     getGranularityPeriod(), getGranularityPeriod());
80         }
81     }
82
83     /**
84      * Stops the periodic monitor.
85      */

86     /*
87      * This method is not synchronized, because if it were there could be a
88      * deadlock with a thread that attempted to get the lock on the monitor
89      * before being interrupted or noticing that it had
90      */

91     public void stop() {
92         if (isActive()) {
93             // Stop the AlarmClock.
94
if (timer != null) {
95                 timer.cancel();
96                 timer = null;
97             }
98             isActive = false;
99         }
100     }
101
102     // GETTERS AND SETTERS
103
//--------------------
104
/**
105      * Sets the granularity period (in milliseconds). <BR>
106      * The default value of the granularity period is 10 seconds.
107      *
108      * @param period
109      * The granularity period value.
110      * @exception java.lang.IllegalArgumentException
111      * The granularity period is less than or equal to zero.
112      *
113      * @see NewMonitor#setGranularityPeriod(long)
114      */

115     public synchronized void setGranularityPeriod(long period)
116             throws java.lang.IllegalArgumentException JavaDoc {
117         super.setGranularityPeriod(period);
118         // Reschedule timer task if timer is already running
119
//
120
if (isActive()) {
121             timer.cancel();
122             timer = new Timer JavaDoc();
123             timer.schedule(new PeriodicAlarmClock(this),
124                     getGranularityPeriod(), getGranularityPeriod());
125         }
126     }
127
128     /**
129      * Gets the derived gauge of the specified object, if this object is
130      * contained in the set of observed MBeans, or <code>null</code>
131      * otherwise.
132      *
133      * @param object
134      * the name of the MBean whose derived gauge is required.
135      *
136      * @return The derived gauge of the specified object.
137      *
138      * @since JMX 1.2
139      */

140     public Object JavaDoc getDerivedGauge(ObjectName JavaDoc object) {
141         int index = indexOf(object);
142         if (index != -1)
143             return derivedGauge[index];
144         else
145             return null;
146     }
147
148     /**
149      * Gets the derived gauge timestamp of the specified object, if this object
150      * is contained in the set of observed MBeans, or <code>null</code>
151      * otherwise.
152      *
153      * @param object
154      * the name of the MBean whose derived gauge timestamp is
155      * required.
156      *
157      * @return The derived gauge timestamp of the specified object.
158      *
159      * @since JMX 1.2
160      */

161     public long getDerivedGaugeTimeStamp(ObjectName JavaDoc object) {
162         int index = indexOf(object);
163         if (index != -1)
164             return derivedGaugeTimestamp[index];
165         else
166             return 0;
167     }
168
169     /*
170      * ------------------------------------------
171      * PRIVATE METHODS
172      * ------------------------------------------
173      */

174     /**
175      * Updates the derived gauge and the derived gauge timestamp attributes of
176      * the observed object at the specified index.
177      *
178      * @param scanObj
179      * The value of the observed attribute.
180      * @param index
181      * The index of the observed object.
182      */

183     private void updateDerivedGauge(Object JavaDoc scanObj, int index) {
184         derivedGaugeTimestamp[index] = (new Date JavaDoc()).getTime();
185         derivedGauge[index] = scanObj;
186     }
187
188     /**
189      * Updates the notification attributes of the observed object at the
190      * specified index and notifies the listeners only once if the
191      * notifyMatch/notifyDiffer flag is set to <CODE>true</CODE>.
192      *
193      * @param index
194      * The index of the observed object.
195      */

196     private void updateNotifications(int index) {
197         sendNotification(
198                 PERIODIC_SAMPLING,
199                 derivedGaugeTimestamp[index], "",
200                 derivedGauge[index], null, index);
201     }
202
203     /*
204      * ------------------------------------------
205      * PACKAGE METHODS
206      * ------------------------------------------
207      */

208     /**
209      * This method is called by the periodic monitor each time the granularity
210      * period has been exceeded.
211      *
212      * @param index
213      * The index of the observed object.
214      */

215     void notifyAlarmClock(int index) {
216         Object JavaDoc scan_obj = null;
217         String JavaDoc notif_type = null;
218         try {
219             if (isActive()) {
220                 
221                 // Check if the observed object and observed attribute are valid.
222
//
223

224                 // Check that neither the observed object nor the observed attribute are null.
225
// If the observed object or observed attribute is null, this means that
226
// the monitor started before a complete initialization and nothing is done.
227
//
228
if ((getObservedObject(index) == null) || (getObservedAttribute() == null)) {
229                     return;
230                 }
231                 
232                 // Check that the observed object is registered in the MBean server and
233
// that the observed attribute belongs to the observed object.
234
//
235
try {
236                     scan_obj = server.getAttribute(getObservedObject(index),
237                             getObservedAttribute());
238                     if (scan_obj == null)
239                         return;
240                 } catch (NullPointerException JavaDoc np_ex) {
241                     if ((alreadyNotifieds[index] & RUNTIME_ERROR_NOTIFIED) != RESET_FLAGS_ALREADY_NOTIFIED) {
242                         return;
243                     } else {
244                         notif_type = MonitorNotification.RUNTIME_ERROR;
245                         setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
246                         throw new MonitorSettingException JavaDoc(
247                                 "The periodic monitor must be registered in the MBean server.");
248                     }
249                 } catch (InstanceNotFoundException JavaDoc inf_ex) {
250                     if ((alreadyNotifieds[index] & OBSERVED_OBJECT_ERROR_NOTIFIED) != RESET_FLAGS_ALREADY_NOTIFIED) {
251                         return;
252                     } else {
253                         notif_type = MonitorNotification.OBSERVED_OBJECT_ERROR;
254                         setAlreadyNotified(index,
255                                 OBSERVED_OBJECT_ERROR_NOTIFIED);
256                         throw new MonitorSettingException JavaDoc(
257                                 "The observed object must be registered in the MBean server.");
258                     }
259                 } catch (AttributeNotFoundException JavaDoc anf_ex) {
260                     if ((alreadyNotifieds[index] & OBSERVED_ATTRIBUTE_ERROR_NOTIFIED) != RESET_FLAGS_ALREADY_NOTIFIED) {
261                         return;
262                     } else {
263                         notif_type = MonitorNotification.OBSERVED_ATTRIBUTE_ERROR;
264                         setAlreadyNotified(index,
265                                 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED);
266                         throw new MonitorSettingException JavaDoc(
267                                 "The observed attribute must be accessible in the observed object.");
268                     }
269                 } catch (MBeanException JavaDoc mb_ex) {
270                     if ((alreadyNotifieds[index] & RUNTIME_ERROR_NOTIFIED) != RESET_FLAGS_ALREADY_NOTIFIED) {
271                         return;
272                     } else {
273                         notif_type = MonitorNotification.RUNTIME_ERROR;
274                         setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
275                         throw new MonitorSettingException JavaDoc(mb_ex.getMessage());
276                     }
277                 } catch (ReflectionException JavaDoc ref_ex) {
278                     if ((alreadyNotifieds[index] & OBSERVED_ATTRIBUTE_ERROR_NOTIFIED) != RESET_FLAGS_ALREADY_NOTIFIED) {
279                         return;
280                     } else {
281                         notif_type = MonitorNotification.OBSERVED_ATTRIBUTE_ERROR;
282                         setAlreadyNotified(index,
283                                 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED);
284                         throw new MonitorSettingException JavaDoc(ref_ex.getMessage());
285                     }
286                 }
287                 // Clear all already notified flags.
288
resetAllAlreadyNotified(index);
289                 // Update the derived gauge attributes.
290
updateDerivedGauge(scan_obj, index);
291                 // Notify the listeners.
292
updateNotifications(index);
293             }
294         } catch (MonitorSettingException JavaDoc ms_ex) {
295             // Create and send the monitor error notification.
296
sendNotification(notif_type, derivedGaugeTimestamp[index], ms_ex
297                     .getMessage(), derivedGauge[index], null, index);
298         }
299     }
300
301     /**
302      * This method is called when adding a new observed object in the vector.
303      * It updates all the specific arrays.
304      *
305      * @param index
306      * The index of the observed object.
307      */

308     void insertSpecificElementAt(int index) {
309         // Update derivedGauge, derivedGaugeTimestamp.
310
insertObjectElementAt(derivedGauge, "", index);
311         insertlongElementAt(derivedGaugeTimestamp, (new Date JavaDoc()).getTime(),
312                 index);
313     }
314
315     /**
316      * This method is called when removing an observed object from the vector.
317      * It updates all the specific arrays.
318      *
319      * @param index
320      * The index of the observed object.
321      */

322     void removeSpecificElementAt(int index) {
323         // Update derivedGauge, derivedGaugeTimestamp.
324
removeObjectElementAt(derivedGauge, index);
325         removelongElementAt(derivedGaugeTimestamp, index);
326     }
327
328     /**
329      * Inserts the specified value at the specified index in the specified
330      * Object array.
331    *
332    * @param array the array to which the element must be added.
333    * @param value the element that must be added.
334    * @param index where the element must be added.
335      */

336     void insertObjectElementAt(Object JavaDoc[] array, Object JavaDoc value, int index) { // !!!
337
ensureObjectCapacity(array, elementCount + 1);
338         System.arraycopy(array, index, array, index + 1, elementCount - index);
339         array[index] = value;
340     }
341
342     /**
343      * Removes the component at the specified index from the specified Object
344      * array.
345    *
346    * @param array the array from which the element must be removed.
347    * @param index index of the element to be removed.
348      */

349     void removeObjectElementAt(Object JavaDoc[] array, int index) {
350         if (index < 0 || index >= elementCount)
351             return;
352         int j = elementCount - index - 1;
353         if (j > 0) {
354             System.arraycopy(array, index + 1, array, index, j);
355         }
356     }
357
358     /**
359      * Increases the capacity of the specified Object array, if necessary, to
360      * ensure that it can hold at least the number of components specified by
361      * the minimum capacity argument.
362    *
363    * @param array the array whose capacity must be increased, if necessary.
364    * @param minCapacity the minimum size the array must have.
365      */

366     void ensureObjectCapacity(Object JavaDoc[] array, int minCapacity) { // !!!
367
int oldCapacity = array.length;
368         // The array must be enlarged.
369
//
370
if (minCapacity > oldCapacity) {
371             Object JavaDoc oldArray[] = array;
372             int newCapacity = oldCapacity + capacityIncrement;
373             if (newCapacity < minCapacity) {
374                 newCapacity = minCapacity;
375             }
376             array = new Number JavaDoc[newCapacity];
377             System.arraycopy(oldArray, 0, array, 0, elementCount);
378         }
379     }
380
381     /**
382      * PeriodicAlarmClock inner class: This class provides a simple
383      * implementation of an alarm clock MBean. The aim of this MBean is to set
384      * up an alarm which wakes up the string monitor every granularity period.
385      */

386     private static class PeriodicAlarmClock extends TimerTask JavaDoc {
387         PeriodicMonitor JavaDoc listener = null;
388         /*
389          * ------------------------------------------
390          * CONSTRUCTORS
391          * ------------------------------------------
392          */

393         public PeriodicAlarmClock(PeriodicMonitor JavaDoc listener) {
394             this.listener = listener;
395         }
396         /*
397          * ------------------------------------------
398          * PUBLIC METHODS
399          * ------------------------------------------
400          */

401         /**
402          * This method is called by the StringAlarmClock thread when it is
403          * started.
404          */

405         public void run() {
406             if (listener.isActive()) {
407                 for (int i = 0; i < listener.elementCount; i++) {
408                     listener.notifyAlarmClock(i);
409                 }
410             }
411         }
412     }
413 }
414
Popular Tags