KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > admin > selfmanagement > event > CounterStatisticMonitor


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 /*
25  * CounterStatisticMonitor.java
26  *
27  * Created on July 11, 2005 3:00 PM
28  */

29
30 package com.sun.enterprise.admin.selfmanagement.event;
31
32 import javax.management.ObjectName JavaDoc;
33 import javax.management.MBeanNotificationInfo JavaDoc;
34 import static com.sun.enterprise.admin.selfmanagement.event.StatisticMonitor.NumericalType.*;
35 import com.sun.appserv.management.event.StatisticMonitorNotification;
36 import static com.sun.appserv.management.event.StatisticMonitorNotification.*;
37 import java.util.logging.Logger JavaDoc;
38 import java.util.logging.Level JavaDoc;
39 import com.sun.logging.LogDomains;
40
41 /**
42  * Defines a monitor MBean designed to observe the values of a counter
43  * attribute, for JDK greater than 1.5.
44  *
45  * <P> A counter monitor sends a {@link
46  * StatisticMonitorNotification#THRESHOLD_VALUE_EXCEEDED threshold
47  * notification} when the value of the counter reaches or exceeds a
48  * threshold known as the comparison level. The notify flag must be
49  * set to <CODE>true</CODE>.
50  *
51  * <P> In addition, an offset mechanism enables particular counting
52  * intervals to be detected. If the offset value is not zero,
53  * whenever the threshold is triggered by the counter value reaching a
54  * comparison level, that comparison level is incremented by the
55  * offset value. This is regarded as taking place instantaneously,
56  * that is, before the count is incremented. Thus, for each level,
57  * the threshold triggers an event notification every time the count
58  * increases by an interval equal to the offset value.
59  *
60  * <P> If the counter can wrap around its maximum value, the modulus
61  * needs to be specified. The modulus is the value at which the
62  * counter is reset to zero.
63  *
64  * <P> If the counter difference mode is used, the value of the
65  * derived gauge is calculated as the difference between the observed
66  * counter values for two successive observations. If this difference
67  * is negative, the value of the derived gauge is incremented by the
68  * value of the modulus. The derived gauge value (V[t]) is calculated
69  * using the following method:
70  *
71  * <UL>
72  * <LI>if (counter[t] - counter[t-GP]) is positive then
73  * V[t] = counter[t] - counter[t-GP]
74  * <LI>if (counter[t] - counter[t-GP]) is negative then
75  * V[t] = counter[t] - counter[t-GP] + MODULUS
76  * </UL>
77  *
78  * This implementation of the counter monitor requires the observed
79  * attribute to be of the type integer (<CODE>Byte</CODE>,
80  * <CODE>Integer</CODE>, <CODE>Short</CODE>, <CODE>Long</CODE>).
81  *
82  * @author Sun Microsystems, Inc
83  */

84 public class CounterStatisticMonitor extends StatisticMonitor implements CounterStatisticMonitorMBean {
85
86     /*
87      * ------------------------------------------
88      * PRIVATE VARIABLES
89      * ------------------------------------------
90      */

91
92     /**
93      * Counter thresholds.
94      * <BR>Each element in this array corresponds to an observed
95      * object in the list.
96      */

97     private Number JavaDoc threshold[] = new Number JavaDoc[capacityIncrement];
98
99     /**
100      * Counter modulus.
101      * <BR>The default value is a null Integer object.
102      */

103     private Number JavaDoc modulus = INTEGER_ZERO;
104
105     /**
106      * Counter offset.
107      * <BR>The default value is a null Integer object.
108      */

109     private Number JavaDoc offset = INTEGER_ZERO;
110
111     /**
112      * Flag indicating if the counter monitor notifies when exceeding
113      * the threshold. The default value is set to
114      * <CODE>false</CODE>.
115      */

116     private boolean notify = false;
117
118     /**
119      * Flag indicating if the counter difference mode is used. If the
120      * counter difference mode is used, the derived gauge is the
121      * difference between two consecutive observed values. Otherwise,
122      * the derived gauge is directly the value of the observed
123      * attribute. The default value is set to <CODE>false</CODE>.
124      */

125     private boolean differenceMode = false;
126
127     /**
128      * Initial counter threshold. This value is used to initialize
129      * the threshold when a new object is added to the list and reset
130      * the threshold to its initial value each time the counter
131      * resets.
132      */

133     private Number JavaDoc initThreshold = INTEGER_ZERO;
134
135     /**
136      * Scan counter value captured by the previous observation.
137      * <BR>Each element in this array corresponds to an observed
138      * object in the list.
139      */

140     private Number JavaDoc previousScanCounter[] = new Number JavaDoc[capacityIncrement];
141
142     /**
143      * Flag indicating if the modulus has been exceeded by the
144      * threshold. This flag is used to reset the threshold once we
145      * are sure that the counter has been resetted.
146      * <BR>Each element in this array corresponds to an observed
147      * object in the list.
148      */

149     private boolean modulusExceeded[] = new boolean[capacityIncrement];
150
151     /**
152      * Derived gauge captured when the modulus has been exceeded by
153      * the threshold. This value is used to check if the counter has
154      * been resetted (in order to reset the threshold).
155      * <BR>Each element in this array corresponds to an observed
156      * object in the list.
157      */

158     private Number JavaDoc derivedGaugeExceeded[] = new Number JavaDoc[capacityIncrement];
159
160     /**
161      * Derived gauge valid.
162      * <BR>Each element in this array corresponds to an observed
163      * object in the list.
164      */

165     private boolean derivedGaugeValid[] = new boolean[capacityIncrement];
166
167     /**
168      * This flag is used to notify only once between two granularity
169      * periods for a given comparison level.
170      * <BR>Each element in this array corresponds to an observed
171      * object in the list.
172      */

173     private boolean eventAlreadyNotified[] = new boolean[capacityIncrement];
174
175     /**
176      * This attribute is used to keep the derived gauge type.
177      * <BR>Each element in this array corresponds to an observed
178      * object in the list.
179      */

180     private NumericalType type[] = new NumericalType[capacityIncrement];
181
182     private static final String JavaDoc[] types = {
183         RUNTIME_ERROR,
184         OBSERVED_OBJECT_ERROR,
185         OBSERVED_ATTRIBUTE_ERROR,
186         OBSERVED_ATTRIBUTE_TYPE_ERROR,
187         THRESHOLD_ERROR,
188         THRESHOLD_VALUE_EXCEEDED
189     };
190
191     private static final MBeanNotificationInfo JavaDoc[] notifsInfo = {
192         new MBeanNotificationInfo JavaDoc(
193             types,
194             "com.sun.appserv.management.event.StatisticMonitorNotification",
195             "Notifications sent by the CounterStatisticMonitor MBean")
196     };
197
198
199     // LOGGER
200
//---------------
201
protected static Logger JavaDoc _logger = LogDomains.getLogger(LogDomains.SELF_MANAGEMENT_LOGGER);
202
203     /*
204      * ------------------------------------------
205      * CONSTRUCTORS
206      * ------------------------------------------
207      */

208
209     /**
210      * Default constructor.
211      */

212     public CounterStatisticMonitor() {
213     }
214
215     /*
216      * ------------------------------------------
217      * PUBLIC METHODS
218      * ------------------------------------------
219      */

220
221     /**
222      * Allows the counter statistic monitor MBean to perform any operations it
223      * needs before being unregistered by the MBean server.
224      *
225      * <P>Resets the threshold values.
226      *
227      * @exception Exception
228      */

229     public void preDeregister() throws Exception JavaDoc {
230
231         // Stop the CounterStatisticMonitor.
232
//
233
super.preDeregister();
234         if ( _logger.isLoggable(Level.FINER) )
235              _logger.log(Level.FINER,"Reset the threshold values");
236
237
238         // Reset values for serialization.
239
//
240
synchronized (this) {
241             for (int i = 0; i < elementCount; i++) {
242                 threshold[i] = initThreshold;
243             }
244         }
245     }
246
247     /**
248      * Starts the counter statistic monitor.
249      */

250     public synchronized void start() {
251         // Reset values.
252
//
253
for (int i = 0; i < elementCount; i++) {
254             threshold[i] = initThreshold;
255             modulusExceeded[i] = false;
256             eventAlreadyNotified[i] = false;
257             previousScanCounter[i] = null;
258         }
259         doStart();
260     }
261
262     /**
263      * Stops the counter statistic monitor.
264      */

265     public synchronized void stop() {
266         doStop();
267     }
268
269     // GETTERS AND SETTERS
270
//--------------------
271

272     /**
273      * Gets the derived gauge of the specified object, if this object is
274      * contained in the set of observed MBeans, or <code>null</code> otherwise.
275      *
276      * @param object the name of the object whose derived gauge is to
277      * be returned.
278      *
279      * @return The derived gauge of the specified object.
280      */

281     public synchronized Number JavaDoc getDerivedGauge(ObjectName JavaDoc object) {
282         return (Number JavaDoc) super.getDerivedGauge(object);
283     }
284
285     /**
286      * Gets the derived gauge timestamp of the specified object, if
287      * this object is contained in the set of observed MBeans, or
288      * <code>null</code> otherwise.
289      *
290      * @param object the name of the object whose derived gauge
291      * timestamp is to be returned.
292      *
293      * @return The derived gauge timestamp of the specified object.
294      */

295     public synchronized long getDerivedGaugeTimeStamp(ObjectName JavaDoc object) {
296         return super.getDerivedGaugeTimeStamp(object);
297     }
298
299     /**
300      * Gets the current threshold value of the specified object, if
301      * this object is contained in the set of observed MBeans, or
302      * <code>null</code> otherwise.
303      *
304      * @param object the name of the object whose threshold is to be
305      * returned.
306      *
307      * @return The threshold value of the specified object.
308      */

309     public synchronized Number JavaDoc getThreshold(ObjectName JavaDoc object) {
310         int index = indexOf(object);
311         if (index != -1)
312             return threshold[index];
313         else
314             return null;
315     }
316
317     /**
318      * Gets the initial threshold value common to all observed objects.
319      *
320      * @return The initial threshold.
321      *
322      * @see #setInitThreshold
323      */

324     public synchronized Number JavaDoc getInitThreshold() {
325         return initThreshold;
326     }
327
328     /**
329      * Sets the initial threshold value common to all observed objects.
330      *
331      * <BR>The current threshold of every object in the set of
332      * observed MBeans is updated consequently.
333      *
334      * @param value The initial threshold value.
335      *
336      * @exception IllegalArgumentException The specified
337      * threshold is null or the threshold value is less than zero.
338      *
339      * @see #getInitThreshold
340      */

341     public synchronized void setInitThreshold(Number JavaDoc value)
342         throws IllegalArgumentException JavaDoc {
343
344         if (value == null) {
345             throw new IllegalArgumentException JavaDoc("Null threshold");
346         }
347         if (value.longValue() < 0L) {
348             throw new IllegalArgumentException JavaDoc("Negative threshold");
349         }
350
351         initThreshold = value;
352
353         for (int i = 0; i < elementCount; i++) {
354             resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED);
355
356             // Reset values.
357
//
358
threshold[i] = value;
359             modulusExceeded[i] = false;
360             eventAlreadyNotified[i] = false;
361         }
362     }
363
364     /**
365      * Returns the derived gauge of the first object in the set of
366      * observed MBeans.
367      *
368      * @return The derived gauge.
369      *
370      * @deprecated As of JMX 1.2, replaced by
371      * {@link #getDerivedGauge(ObjectName)}
372      */

373     @Deprecated JavaDoc
374     public synchronized Number JavaDoc getDerivedGauge() {
375         return (Number JavaDoc) derivedGauge[0];
376     }
377
378     /**
379      * Gets the derived gauge timestamp of the first object in the set
380      * of observed MBeans.
381      *
382      * @return The derived gauge timestamp.
383      *
384      * @deprecated As of JMX 1.2, replaced by
385      * {@link #getDerivedGaugeTimeStamp(ObjectName)}
386      */

387     @Deprecated JavaDoc
388     public synchronized long getDerivedGaugeTimeStamp() {
389         return derivedGaugeTimestamp[0];
390     }
391
392     /**
393      * Gets the threshold value of the first object in the set of
394      * observed MBeans.
395      *
396      * @return The threshold value.
397      *
398      * @see #setThreshold
399      *
400      * @deprecated As of JMX 1.2, replaced by {@link #getThreshold(ObjectName)}
401      */

402     @Deprecated JavaDoc
403     public synchronized Number JavaDoc getThreshold() {
404         return threshold[0];
405     }
406
407     /**
408      * Sets the initial threshold value.
409      *
410      * @param value The initial threshold value.
411      *
412      * @exception IllegalArgumentException The specified threshold is
413      * null or the threshold value is less than zero.
414      *
415      * @see #getThreshold()
416      *
417      * @deprecated As of JMX 1.2, replaced by {@link #setInitThreshold}
418      */

419     @Deprecated JavaDoc
420     public synchronized void setThreshold(Number JavaDoc value)
421         throws IllegalArgumentException JavaDoc {
422         setInitThreshold(value);
423     }
424
425     /**
426      * Gets the offset value common to all observed MBeans.
427      *
428      * @return The offset value.
429      *
430      * @see #setOffset
431      */

432     public synchronized Number JavaDoc getOffset() {
433         return offset;
434     }
435
436     /**
437      * Sets the offset value common to all observed MBeans.
438      *
439      * @param value The offset value.
440      *
441      * @exception IllegalArgumentException The specified
442      * offset is null or the offset value is less than zero.
443      *
444      * @see #getOffset
445      */

446     public synchronized void setOffset(Number JavaDoc value)
447         throws IllegalArgumentException JavaDoc {
448
449         if (value == null) {
450             throw new IllegalArgumentException JavaDoc("Null offset");
451         }
452         if (value.longValue() < 0L) {
453             throw new IllegalArgumentException JavaDoc("Negative offset");
454         }
455
456         offset = value;
457
458         for (int i = 0; i < elementCount; i++) {
459             resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED);
460         }
461     }
462
463     /**
464      * Gets the modulus value common to all observed MBeans.
465      *
466      * @see #setModulus
467      *
468      * @return The modulus value.
469      */

470     public synchronized Number JavaDoc getModulus() {
471         return modulus;
472     }
473
474     /**
475      * Sets the modulus value common to all observed MBeans.
476      *
477      * @param value The modulus value.
478      *
479      * @exception IllegalArgumentException The specified
480      * modulus is null or the modulus value is less than zero.
481      *
482      * @see #getModulus
483      */

484     public synchronized void setModulus(Number JavaDoc value)
485             throws IllegalArgumentException JavaDoc {
486
487         if (value == null) {
488             throw new IllegalArgumentException JavaDoc("Null modulus");
489         }
490         if (value.longValue() < 0L) {
491             throw new IllegalArgumentException JavaDoc("Negative modulus");
492         }
493
494         modulus = value;
495
496         for (int i = 0; i < elementCount; i++) {
497             resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED);
498
499             // Reset values.
500
//
501
modulusExceeded[i] = false;
502         }
503     }
504
505     /**
506      * Gets the notification's on/off switch value common to all
507      * observed MBeans.
508      *
509      * @return <CODE>true</CODE> if the counter monitor notifies when
510      * exceeding the threshold, <CODE>false</CODE> otherwise.
511      *
512      * @see #setNotify
513      */

514     public synchronized boolean getNotify() {
515         return notify;
516     }
517
518     /**
519      * Sets the notification's on/off switch value common to all
520      * observed MBeans.
521      *
522      * @param value The notification's on/off switch value.
523      *
524      * @see #getNotify
525      */

526     public synchronized void setNotify(boolean value) {
527         notify = value;
528     }
529
530     /**
531      * Gets the difference mode flag value common to all observed MBeans.
532      *
533      * @return <CODE>true</CODE> if the difference mode is used,
534      * <CODE>false</CODE> otherwise.
535      *
536      * @see #setDifferenceMode
537      */

538     public synchronized boolean getDifferenceMode() {
539         return differenceMode;
540     }
541
542     /**
543      * Sets the difference mode flag value common to all observed MBeans.
544      *
545      * @param value The difference mode flag value.
546      *
547      * @see #getDifferenceMode
548      */

549     public synchronized void setDifferenceMode(boolean value) {
550         differenceMode = value;
551
552         for (int i = 0; i < elementCount; i++) {
553             // Reset values.
554
//
555
threshold[i] = initThreshold;
556             modulusExceeded[i] = false;
557             eventAlreadyNotified[i] = false;
558             previousScanCounter[i] = null;
559         }
560     }
561
562     /**
563      * Returns a <CODE>NotificationInfo</CODE> object containing the
564      * name of the Java class of the notification and the notification
565      * types sent by the counter monitor.
566      */

567     public MBeanNotificationInfo JavaDoc[] getNotificationInfo() {
568         return notifsInfo;
569     }
570
571     /*
572      * ------------------------------------------
573      * PRIVATE METHODS
574      * ------------------------------------------
575      */

576
577     /**
578      * Updates the derived gauge attribute of the observed object at
579      * the specified index.
580      *
581      * @param scanCounter The value of the observed attribute.
582      * @param index The index of the observed object.
583      * @return <CODE>true</CODE> if the derived gauge value is valid,
584      * <CODE>false</CODE> otherwise. The derived gauge value is
585      * invalid when the differenceMode flag is set to
586      * <CODE>true</CODE> and it is the first notification (so we
587      * haven't 2 consecutive values to update the derived gauge).
588      */

589     private synchronized boolean updateDerivedGauge(Object JavaDoc scanCounter,
590                                                     int index) {
591
592         boolean is_derived_gauge_valid;
593
594         // The counter difference mode is used.
595
//
596
if (differenceMode) {
597
598             // The previous scan counter has been initialized.
599
//
600
if (previousScanCounter[index] != null) {
601                 setDerivedGaugeWithDifference((Number JavaDoc)scanCounter, null, index);
602
603                 // If derived gauge is negative it means that the
604
// counter has wrapped around and the value of the
605
// threshold needs to be reset to its initial value.
606
//
607
if (((Number JavaDoc)derivedGauge[index]).longValue() < 0L) {
608                     if (modulus.longValue() > 0L) {
609                         setDerivedGaugeWithDifference((Number JavaDoc)scanCounter,
610                                                       (Number JavaDoc)modulus, index);
611                     }
612                     threshold[index] = initThreshold;
613                     eventAlreadyNotified[index] = false;
614                 }
615                 is_derived_gauge_valid = true;
616             }
617             // The previous scan counter has not been initialized.
618
// We cannot update the derived gauge...
619
//
620
else {
621                 is_derived_gauge_valid = false;
622             }
623             previousScanCounter[index] = (Number JavaDoc)scanCounter;
624         }
625         // The counter difference mode is not used.
626
//
627
else {
628             derivedGauge[index] = (Number JavaDoc)scanCounter;
629             is_derived_gauge_valid = true;
630         }
631         return is_derived_gauge_valid;
632     }
633
634     /**
635      * Updates the notification attribute of the observed object at the
636      * specified index and notifies the listeners only once if the notify flag
637      * is set to <CODE>true</CODE>.
638      * @param index The index of the observed object.
639      */

640     private StatisticMonitorNotification updateNotifications(int index) {
641
642         StatisticMonitorNotification n = null;
643
644         synchronized(this) {
645             // Send notification if notify is true.
646
//
647
if (!eventAlreadyNotified[index]) {
648                 if (((Number JavaDoc)derivedGauge[index]).longValue() >=
649                     threshold[index].longValue()) {
650                     if (notify) {
651                         n = new StatisticMonitorNotification(THRESHOLD_VALUE_EXCEEDED,
652                                                     this,
653                                                     0,
654                                                     0,
655                                                     "",
656                                                     null,
657                                                     null,
658                                                     null,
659                                                     threshold[index]);
660                     }
661                     if (!differenceMode) {
662                         eventAlreadyNotified[index] = true;
663                     }
664                 }
665             } else {
666                 if ( _logger.isLoggable(Level.INFO) ) {
667                     _logger.log(Level.INFO,"The notification:" +
668                           "\n\tNotification observed object = " +
669                           getObservedObject(index) +
670                           "\n\tNotification observed attribute = " +
671                           getObservedAttribute() +
672                           "\n\tNotification threshold level = " +
673                           threshold[index] +
674                           "\n\tNotification derived gauge = " +
675                           derivedGauge[index] +
676                           "\nhas already been sent");
677                 }
678             }
679         }
680
681         return n;
682     }
683
684     /**
685      * Updates the threshold attribute of the observed object at the
686      * specified index.
687      * @param index The index of the observed object.
688      */

689     private synchronized void updateThreshold(int index) {
690
691         // Calculate the new threshold value if the threshold has been
692
// exceeded and if the offset value is greater than zero.
693
//
694
if (((Number JavaDoc)derivedGauge[index]).longValue() >=
695             threshold[index].longValue()) {
696
697             if (offset.longValue() > 0L) {
698
699                 // Increment the threshold until its value is greater
700
// than the one for the current derived gauge.
701
//
702
long threshold_value = threshold[index].longValue();
703                 while (((Number JavaDoc)derivedGauge[index]).longValue() >=
704                        threshold_value) {
705                     threshold_value += offset.longValue();
706                 }
707
708                 // Set threshold attribute.
709
//
710
switch(type[index]) {
711                     case INTEGER:
712                         threshold[index] = new Integer JavaDoc((int)threshold_value);
713                         break;
714                     case BYTE:
715                         threshold[index] = new Byte JavaDoc((byte)threshold_value);
716                         break;
717                     case SHORT:
718                         threshold[index] = new Short JavaDoc((short)threshold_value);
719                         break;
720                     case LONG:
721                         threshold[index] = new Long JavaDoc((long)threshold_value);
722                         break;
723                     default:
724                         // Should never occur...
725
if ( _logger.isLoggable(Level.WARNING) )
726                             _logger.log(Level.WARNING,"Threshold Type is Invalid");
727                         break;
728                 }
729
730                 // If the counter can wrap around when it reaches
731
// its maximum and we are not dealing with counter
732
// differences then we need to reset the threshold
733
// to its initial value too.
734
//
735
if (!differenceMode) {
736                     if (modulus.longValue() > 0L) {
737                         if (threshold[index].longValue() >
738                             modulus.longValue()) {
739                             modulusExceeded[index] = true;
740                             derivedGaugeExceeded[index] =
741                                     (Number JavaDoc) derivedGauge[index];
742                         }
743                     }
744                 }
745
746                 // Threshold value has been modified so we can notify again.
747
//
748
eventAlreadyNotified[index] = false;
749             } else {
750                 modulusExceeded[index] = true;
751                 derivedGaugeExceeded[index] = (Number JavaDoc) derivedGauge[index];
752             }
753         }
754     }
755
756     /**
757      * Sets the derived gauge of the specified index when the
758      * differenceMode flag is set to <CODE>true</CODE>. Integer types
759      * only are allowed.
760      *
761      * @param scanCounter The value of the observed attribute.
762      * @param mod The counter modulus value.
763      * @param index The index of the observed object.
764      */

765     private synchronized void setDerivedGaugeWithDifference(Number JavaDoc scanCounter,
766                                                             Number JavaDoc mod,
767                                                             int index) {
768         /* We do the arithmetic using longs here even though the
769            result may end up in a smaller type. Since
770            l == (byte)l (mod 256) for any long l,
771            (byte) ((byte)l1 + (byte)l2) == (byte) (l1 + l2),
772            and likewise for subtraction. So it's the same as if
773            we had done the arithmetic in the smaller type.*/

774
775         long derived =
776             scanCounter.longValue() - previousScanCounter[index].longValue();
777         if (mod != null)
778             derived += modulus.longValue();
779
780         switch (type[index]) {
781         case INTEGER: derivedGauge[index] = new Integer JavaDoc((int) derived); break;
782         case BYTE: derivedGauge[index] = new Byte JavaDoc((byte) derived); break;
783         case SHORT: derivedGauge[index] = new Short JavaDoc((short) derived); break;
784         case LONG: derivedGauge[index] = new Long JavaDoc(derived); break;
785         default:
786             // Should never occur...
787
if ( _logger.isLoggable(Level.WARNING) )
788                 _logger.log(Level.WARNING,"Threshold Type is Invalid");
789             break;
790         }
791     }
792
793     /*
794      * ------------------------------------------
795      * PACKAGE METHODS
796      * ------------------------------------------
797      */

798
799     /**
800      * This method globally sets the derived gauge type for the given
801      * "object" and "attribute" after checking that the type of the
802      * supplied observed attribute value is one of the value types
803      * supported by this monitor.
804      */

805     boolean isComparableTypeValid(ObjectName JavaDoc object,
806                                   String JavaDoc attribute,
807                                   Comparable JavaDoc<?> value) {
808         int index = indexOf(object);
809
810         // Check that the observed attribute is of type "Integer".
811
//
812
if (value instanceof Integer JavaDoc) {
813             type[index] = INTEGER;
814         } else if (value instanceof Byte JavaDoc) {
815             type[index] = BYTE;
816         } else if (value instanceof Short JavaDoc) {
817             type[index] = SHORT;
818         } else if (value instanceof Long JavaDoc) {
819             type[index] = LONG;
820         } else {
821             return false;
822         }
823         return true;
824     }
825
826     Comparable JavaDoc<?> getDerivedGaugeFromComparable(ObjectName JavaDoc object,
827                                                 String JavaDoc attribute,
828                                                 Comparable JavaDoc<?> value) {
829         int index = indexOf(object);
830
831         // Check if counter has wrapped around.
832
//
833
if (modulusExceeded[index]) {
834             if (((Number JavaDoc)derivedGauge[index]).longValue() <
835                 derivedGaugeExceeded[index].longValue()) {
836                     threshold[index] = initThreshold;
837                     modulusExceeded[index] = false;
838                     eventAlreadyNotified[index] = false;
839             }
840         }
841
842         // Update the derived gauge attributes and check the
843
// validity of the new value. The derived gauge value
844
// is invalid when the differenceMode flag is set to
845
// true and it is the first notification, i.e. we
846
// haven't got 2 consecutive values to update the
847
// derived gauge.
848
//
849
derivedGaugeValid[index] = updateDerivedGauge(value, index);
850
851         return (Comparable JavaDoc<?>) derivedGauge[index];
852     }
853
854     void onErrorNotification(StatisticMonitorNotification notification) {
855         int index = indexOf(notification.getObservedObject());
856         synchronized(this) {
857             // Reset values.
858
//
859
modulusExceeded[index] = false;
860             eventAlreadyNotified[index] = false;
861             previousScanCounter[index] = null;
862         }
863     }
864
865     StatisticMonitorNotification buildAlarmNotification(ObjectName JavaDoc object,
866                                                String JavaDoc attribute,
867                                                Comparable JavaDoc<?> value) {
868         int index = indexOf(object);
869
870         // Notify the listeners and update the threshold if
871
// the updated derived gauge value is valid.
872
//
873
StatisticMonitorNotification alarm = null;
874         if (derivedGaugeValid[index]) {
875             alarm = updateNotifications(index);
876             updateThreshold(index);
877         }
878         return alarm;
879     }
880
881     /**
882      * Tests if the threshold, offset and modulus of the specified index are
883      * of the same type as the counter. Only integer types are allowed.
884      *
885      * Note:
886      * If the optional offset or modulus have not been initialized, their
887      * default value is an Integer object with a value equal to zero.
888      *
889      * @param object The observed object.
890      * @param attribute The observed attribute.
891      * @param value The sample value.
892      * @return <CODE>true</CODE> if type is the same,
893      * <CODE>false</CODE> otherwise.
894      */

895     synchronized boolean isThresholdTypeValid(ObjectName JavaDoc object,
896                                               String JavaDoc attribute,
897                                               Comparable JavaDoc<?> value) {
898         int index = indexOf(object);
899         Class JavaDoc<? extends Number JavaDoc> c = classForType(type[index]);
900         return (c.isInstance(threshold[index]) &&
901                 isValidForType(offset, c) &&
902                 isValidForType(modulus, c));
903     }
904
905     /**
906      * This method is called when adding a new observed object in the vector.
907      * It updates all the counter specific arrays.
908      * @param index The index of the observed object.
909      */

910     synchronized void insertSpecificElementAt(int index) {
911         // Update threshold, previousScanCounter, derivedGaugeExceeded,
912
// derivedGaugeValid, modulusExceeded, eventAlreadyNotified and
913
// type arrays.
914
//
915
if (elementCount >= threshold.length) {
916             threshold = expandArray(threshold);
917             previousScanCounter = expandArray(previousScanCounter);
918             derivedGaugeExceeded = expandArray(derivedGaugeExceeded);
919             derivedGaugeValid = expandArray(derivedGaugeValid);
920             modulusExceeded = expandArray(modulusExceeded);
921             eventAlreadyNotified = expandArray(eventAlreadyNotified);
922             type = expandArray(type);
923         }
924         threshold[index] = INTEGER_ZERO;
925         previousScanCounter[index] = null;
926         derivedGaugeExceeded[index] = null;
927         derivedGaugeValid[index] = false;
928         modulusExceeded[index] = false;
929         eventAlreadyNotified[index] = false;
930         type[index] = INTEGER;
931     }
932
933     /**
934      * This method is called when removing an observed object from the vector.
935      * It updates all the counter specific arrays.
936      * @param index The index of the observed object.
937      */

938     synchronized void removeSpecificElementAt(int index) {
939         // Update threshold, previousScanCounter, derivedGaugeExceeded,
940
// derivedGaugeValid, modulusExceeded, eventAlreadyNotified and
941
// type arrays.
942
//
943
removeElementAt(threshold, index);
944         removeElementAt(previousScanCounter, index);
945         removeElementAt(derivedGaugeExceeded, index);
946         removeElementAt(derivedGaugeValid, index);
947         removeElementAt(modulusExceeded, index);
948         removeElementAt(eventAlreadyNotified, index);
949         removeElementAt(type, index);
950     }
951 }
952
Popular Tags