FileDocCategorySizeDatePackage
StatisticMonitor.javaAPI DocGlassfish v2 API56415Fri May 04 22:33:44 BST 2007com.sun.enterprise.admin.selfmanagement.event

StatisticMonitor

public abstract class StatisticMonitor extends NotificationBroadcasterSupport implements StatisticMonitorMBean, MBeanRegistration
Defines the part common to all monitor MBeans. A statistic monitor MBean monitors values of an attribute common to a set of observed MBeans. The observed attribute is monitored at intervals specified by the granularity period. A gauge value (derived gauge) is derived from the values of the observed attribute. Used for JDK version greater than 1.5
author
Sun Microsystems, Inc

Fields Summary
private List
observedObjects
List of MBeans to which the attribute to observe belongs.
private String
observedAttribute
Attribute to observe.
private long
granularityPeriod
Monitor granularity period (in milliseconds). The default value is set to 10 seconds.
private boolean
isActive
Monitor state. The default value is set to false.
private long
sequenceNumber
Monitor sequence number. The default value is set to 0.
private boolean
isComplexTypeAttribute
Complex type attribute flag. The default value is set to false.
private String
firstAttribute
First attribute name extracted from complex type attribute name.
private List
remainingAttributes
Remaining attribute names extracted from complex type attribute name.
private AccessControlContext
acc
AccessControlContext of the Monitor.start() caller.
private static final ScheduledExecutorService
scheduler
Scheduler Service.
private static final int
maximumPoolSize
Maximum Pool Size
private static final ExecutorService
executor
Executor Service.
protected static final Logger
_logger
private MonitorTask
monitorTask
Monitor task to be executed by the Executor Service.
private Runnable
schedulerTask
Scheduler task to be executed by the Scheduler Service.
private ScheduledFuture
schedulerFuture
ScheduledFuture associated to the current scheduler task.
protected static final int
capacityIncrement
The amount by which the capacity of the monitor arrays are automatically incremented when their size becomes greater than their capacity.
protected int
elementCount
The number of valid components in the vector of observed objects.
protected int
alreadyNotified
Monitor errors that have already been notified.
protected int[]
alreadyNotifieds

Selected monitor errors that have already been notified.

Each element in this array corresponds to an observed object in the vector. It contains a bit mask of the flags {@link #OBSERVED_OBJECT_ERROR_NOTIFIED} etc, indicating whether the corresponding notification has already been sent for the MBean being monitored.

protected MBeanServer
server
Reference to the MBean server. This reference is null when the monitor MBean is not registered in an MBean server. This reference is initialized before the monitor MBean is registered in the MBean server.
protected static final int
RESET_FLAGS_ALREADY_NOTIFIED
This flag is used to reset the {@link #alreadyNotifieds alreadyNotifieds} monitor attribute.
protected static final int
OBSERVED_OBJECT_ERROR_NOTIFIED
Flag denoting that a notification has occurred after changing the observed object. This flag is used to check that the new observed object is registered in the MBean server at the time of the first notification.
protected static final int
OBSERVED_ATTRIBUTE_ERROR_NOTIFIED
Flag denoting that a notification has occurred after changing the observed attribute. This flag is used to check that the new observed attribute belongs to the observed object at the time of the first notification.
protected static final int
OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED
Flag denoting that a notification has occurred after changing the observed object or the observed attribute. This flag is used to check that the observed attribute type is correct (depending on the monitor in use) at the time of the first notification.
protected static final int
RUNTIME_ERROR_NOTIFIED
Flag denoting that a notification has occurred after changing the observed object or the observed attribute. This flag is used to notify any exception (except the cases described above) when trying to get the value of the observed attribute at the time of the first notification.
static final int
THRESHOLD_ERROR_NOTIFIED
Flag denoting that a notification has occured after changing the threshold. This flag is used to notify any exception related to invalid thresholds settings.
Object[]
derivedGauge
Derived gauges.
Each element in this array corresponds to an observed object in the list.
long[]
derivedGaugeTimestamp
Derived gauges' timestamps.
Each element in this array corresponds to an observed object in the list.
static final Integer
INTEGER_ZERO
Constant used to initialize all the numeric values.
Constructors Summary
Methods Summary
public synchronized voidaddObservedObject(javax.management.ObjectName object)
Adds the specified object in the set of observed MBeans, if this object is not already present.

param
object The object to observe.
exception
IllegalArgumentException The specified object is null.
since.unbundled
JMX 1.2


        if (object == null) {
            throw new IllegalArgumentException("Null observed object");
        }

        // Check that the specified object is not already contained.
        //
        if (observedObjects.contains(object)) {
            return;
        }

        // Add the specified object in the list.
        //
        observedObjects.add(object);

        // Update arrays.
        //
        if (elementCount >= alreadyNotifieds.length) {
            alreadyNotifieds = expandArray(alreadyNotifieds);
            derivedGauge = expandArray(derivedGauge);
            derivedGaugeTimestamp = expandArray(derivedGaugeTimestamp);
        }
        alreadyNotifieds[elementCount] = RESET_FLAGS_ALREADY_NOTIFIED;
        updateDeprecatedAlreadyNotified();
        derivedGauge[elementCount] = null;
        derivedGaugeTimestamp[elementCount] = System.currentTimeMillis();

        // Update other specific arrays.
        //
        insertSpecificElementAt(elementCount);

        // Update elementCount.
        //
        elementCount++;
    
synchronized booleanalreadyNotified(int index, int mask)

        return ((alreadyNotifieds[index] & mask) != 0);
    
com.sun.appserv.management.event.StatisticMonitorNotificationbuildAlarmNotification(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return null;
    
java.lang.StringbuildErrorNotification(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return null;
    
static java.lang.ClassclassForType(com.sun.enterprise.admin.selfmanagement.event.StatisticMonitor$NumericalType type)

        switch (type) {
            case BYTE:
                return Byte.class;
            case SHORT:
                return Short.class;
            case INTEGER:
                return Integer.class;
            case LONG:
                return Long.class;
            case FLOAT:
                return Float.class;
            case DOUBLE:
                return Double.class;
            default:
                throw new IllegalArgumentException(
                    "Unsupported numerical type");
        }
    
public synchronized booleancontainsObservedObject(javax.management.ObjectName object)
Tests whether the specified object is in the set of observed MBeans.

param
object The object to check.
return
true if the specified object is present, false otherwise.
since.unbundled
JMX 1.2

        return observedObjects.contains(object);
    
voiddoStart()
Starts the statistic monitor.

        if ( _logger.isLoggable(Level.FINER) )
             _logger.log(Level.FINER,"Start the statistic monitor");

        synchronized(this) {
            if (isActive()) {
                if ( _logger.isLoggable(Level.WARNING) )
                    _logger.log(Level.WARNING,"The StatisticMonitor is already active");
                return;
            }

            isActive = true;

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            firstAttribute = null;
            remainingAttributes.clear();
            isComplexTypeAttribute = false;

            // Cache the AccessControlContext of the Monitor.start() caller.
            // The monitor tasks will be executed within this context.
            //
            acc = AccessController.getContext();

            // Start the scheduler.
            //
            schedulerFuture = scheduler.schedule(schedulerTask,
                                                 getGranularityPeriod(),
                                                 TimeUnit.MILLISECONDS);
        }
    
voiddoStop()
Stops the statistic monitor.

        if ( _logger.isLoggable(Level.FINER) )
             _logger.log(Level.FINER,"Stop the StatisticMonitor");

        synchronized(this) {
            if (!isActive()) {
                if ( _logger.isLoggable(Level.WARNING) )
                    _logger.log(Level.WARNING,"StatisticMonitor is not active");
                return;
            }

            isActive = false;

            // Cancel the scheduler task associated with the scheduler.
            //
            schedulerFuture.cancel(false);

            // Reset the AccessControlContext.
            //
            acc = null;

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            firstAttribute = null;
            remainingAttributes.clear();
            isComplexTypeAttribute = false;
        }
    
int[]expandArray(int[] array)
Expands the specified int array.

        int[] newArray = new int[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
long[]expandArray(long[] array)
Expands the specified long array.

        long[] newArray = new long[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
boolean[]expandArray(boolean[] array)
Expands the specified boolean array.

        boolean[] newArray = new boolean[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
java.lang.Number[]expandArray(java.lang.Number[] array)
Expands the specified Number array.

        Number[] newArray = new Number[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
java.lang.String[]expandArray(java.lang.String[] array)
Expands the specified String array.

        String[] newArray = new String[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
com.sun.enterprise.admin.selfmanagement.event.StatisticMonitor$NumericalType[]expandArray(com.sun.enterprise.admin.selfmanagement.event.StatisticMonitor$NumericalType[] array)
Expands the specified NumericalType array.

        NumericalType[] newArray =
            new NumericalType[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
java.lang.Object[]expandArray(java.lang.Object[] array)
Expands the specified Object array.

        Object[] newArray = new Object[array.length + capacityIncrement];
        System.arraycopy(array, 0, newArray, 0, array.length);
        return newArray;
    
java.lang.ObjectgetAttribute(javax.management.MBeanServerConnection mbsc, javax.management.ObjectName object, java.lang.String attribute)

        // Check for complex type attribute
        //
        if (firstAttribute == null) {
            if (attribute.indexOf('.") != -1) {
                MBeanInfo mbi;
                try {
                    mbi = mbsc.getMBeanInfo(object);
                } catch (IntrospectionException e) {
                    throw new IllegalArgumentException(e);
                }
                MBeanAttributeInfo mbaiArray[] = mbi.getAttributes();
                for (MBeanAttributeInfo mbai : mbaiArray) {
                    if (attribute.equals(mbai.getName())) {
                        firstAttribute = attribute;
                        break;
                    }
                }
                if (firstAttribute == null) {
                    String tokens[] = attribute.split("\\.", -1);
                    firstAttribute = tokens[0];
                    for (int i = 1; i < tokens.length; i++)
                        remainingAttributes.add(tokens[i]);
                    isComplexTypeAttribute = true;
                }
            } else {
                firstAttribute = attribute;
            }
        }
        return mbsc.getAttribute(object, firstAttribute);
    
java.lang.ComparablegetComparableFromAttribute(javax.management.ObjectName object, java.lang.String attribute, java.lang.Object value)

        if (isComplexTypeAttribute) {
            Object v = value;
            for (String attr : remainingAttributes)
                v = introspect(object, attr, v);
            return (Comparable<?>) v;
        } else {
            return (Comparable<?>) value;
        }
    
synchronized java.lang.ObjectgetDerivedGauge(javax.management.ObjectName object)
Gets the derived gauge of the specified object, if this object is contained in the set of observed MBeans, or null otherwise.

param
object the name of the object whose derived gauge is to be returned.
return
The derived gauge of the specified object.
since
6.0

        int index = indexOf(object);
        if (index != -1) {
            return derivedGauge[index];
        }
        else
            return null;
    
java.lang.ComparablegetDerivedGaugeFromComparable(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return (Comparable<?>) value;
    
synchronized longgetDerivedGaugeTimeStamp(javax.management.ObjectName object)
Gets the derived gauge timestamp of the specified object, if this object is contained in the set of observed MBeans, or null otherwise.

param
object the name of the object whose derived gauge timestamp is to be returned.
return
The derived gauge timestamp of the specified object.
since.unbundled
JMX 1.2

        int index = indexOf(object);
        if (index != -1)
            return derivedGaugeTimestamp[index];
        else
            return 0;
    
public synchronized longgetGranularityPeriod()
Gets the granularity period (in milliseconds).
The default value of the granularity period is 10 seconds.

return
The granularity period value.
see
#setGranularityPeriod

        return granularityPeriod;
    
public java.lang.StringgetObservedAttribute()
Gets the attribute being observed.
The observed attribute is not initialized by default (set to null).

return
The attribute being observed.
see
#setObservedAttribute

        return observedAttribute;
    
synchronized javax.management.ObjectNamegetObservedObject(int index)
Gets the {@link ObjectName} of the object at the specified index in the list of observed MBeans.

return
The observed object at the specified index.
exception
ArrayIndexOutOfBoundsException If the index is invalid.

        return observedObjects.get(index);
    
public synchronized javax.management.ObjectNamegetObservedObject()
Returns the object name of the first object in the set of observed MBeans, or null if there is no such object.

return
The object being observed.
see
#setObservedObject(ObjectName)
deprecated
As of JMX 1.2, replaced by {@link #getObservedObjects}

        if (observedObjects.isEmpty()) {
            return null;
        } else {
            return observedObjects.get(0);
        }
    
public synchronized javax.management.ObjectName[]getObservedObjects()
Returns an array containing the objects being observed.

return
The objects being observed.
since.unbundled
JMX 1.2

        return observedObjects.toArray(new ObjectName[0]);
    
synchronized intindexOf(javax.management.ObjectName object)
Searches for the first occurence of the given argument, testing for equality using the equals method.

        return observedObjects.indexOf(object);
    
voidinsertSpecificElementAt(int index)
This method is overridden by the specific monitor classes (Counter, Gauge and String). It updates all the specific arrays after adding a new observed object in the list. The method is not abstract so that this class can be subclassed by classes outside this package.

java.lang.Objectintrospect(javax.management.ObjectName object, java.lang.String attribute, java.lang.Object value)

        try {
            if (value.getClass().isArray() && attribute.equals("length")) {
                return Array.getLength(value);
            } else if (value instanceof CompositeData) {
                return ((CompositeData) value).get(attribute);
            } else {
                // Java Beans introspection
                //
                BeanInfo bi = Introspector.getBeanInfo(value.getClass());
                PropertyDescriptor[] pds = bi.getPropertyDescriptors();
                for (PropertyDescriptor pd : pds)
                    if (pd.getName().equals(attribute)) {
                        return pd.getReadMethod().invoke(value);
                    }
                throw new AttributeNotFoundException(
                    "Could not find the getter method for the property " +
                    attribute + " using the Java Beans introspector");
            }
        } catch (InvocationTargetException e) {
            throw new IllegalArgumentException(e);
        } catch (AttributeNotFoundException e) {
            throw e;
        } catch (Exception e) {
            throw (AttributeNotFoundException)
                new AttributeNotFoundException(e.getMessage()).initCause(e);
        }
    
public synchronized booleanisActive()
Tests whether the statistic monitor MBean is active. A statistic monitor MBean is marked active when the {@link #start start} method is called. It becomes inactive when the {@link #stop stop} method is called.

return
true if the statistic monitor MBean is active, false otherwise.

        return isActive;
    
booleanisComparableTypeValid(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return true;
    
booleanisThresholdTypeValid(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return true;
    
static booleanisValidForType(java.lang.Object value, java.lang.Class c)

        return ((value == INTEGER_ZERO) || c.isInstance(value));
    
private voidmonitor(int index)
This method is called by the monitor each time the granularity period has been exceeded.

param
index The index of the observed object.


        String notifType = null;
        String msg = null;
        Object derGauge = null;
        Object trigger = null;
        ObjectName object = null;
        Comparable<?> value = null;
        StatisticMonitorNotification alarm = null;

        synchronized(this) {
            if (!isActive())
                return;

            // Check that neither the observed object nor the
            // observed attribute are null.  If the observed
            // object or observed attribute is null, this means
            // that the monitor started before a complete
            // initialization and nothing is done.
            //
            object = getObservedObject(index);
            String attribute = getObservedAttribute();
            if (object == null || attribute == null) {
                return;
            }

            // Check that the observed object is registered in the
            // MBean server and that the observed attribute
            // belongs to the observed object.
            //
            Object attributeValue = null;
            try {
                attributeValue = getAttribute(server, object, attribute);
                if (attributeValue == null)
                    if (alreadyNotified(index,
                                        OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_TYPE_ERROR;
                        setAlreadyNotified(
                                  index,
                                  OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED);
                        msg = "The observed attribute value is null.";
                        if ( _logger.isLoggable(Level.WARNING) )
                            _logger.log(Level.WARNING,msg);
                    }
            } catch (NullPointerException np_ex) {
                if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = RUNTIME_ERROR;
                    setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                    msg =
                        "The monitor must be registered in the MBean " +
                        "server or an MBeanServerConnection must be " +
                        "explicitly supplied.";
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, np_ex.toString());
                    }
                }
            } catch (InstanceNotFoundException inf_ex) {
                if (alreadyNotified(index, OBSERVED_OBJECT_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = OBSERVED_OBJECT_ERROR;
                    setAlreadyNotified(index, OBSERVED_OBJECT_ERROR_NOTIFIED);
                    msg =
                        "The observed object must be accessible in " +
                        "the MBeanServerConnection.";
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, inf_ex.toString());
                    }
                }
            } catch (AttributeNotFoundException anf_ex) {
                if (alreadyNotified(index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = OBSERVED_ATTRIBUTE_ERROR;
                    setAlreadyNotified(index,
                                       OBSERVED_ATTRIBUTE_ERROR_NOTIFIED);
                    msg =
                        "The observed attribute must be accessible in " +
                        "the observed object.";
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, anf_ex.toString());
                    }

                }
            } catch (MBeanException mb_ex) {
                if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = RUNTIME_ERROR;
                    setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                    msg = mb_ex.getMessage();
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, mb_ex.toString());
                    }
                }
            } catch (ReflectionException ref_ex) {
                if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED)) {
                    return;
                } else {
                    notifType = RUNTIME_ERROR;
                    setAlreadyNotified(index,
                                       RUNTIME_ERROR_NOTIFIED);
                    msg = ref_ex.getMessage();
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, ref_ex.toString());
                    }
                }
            } catch (IOException io_ex) {
                if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = RUNTIME_ERROR;
                    setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                    msg = io_ex.getMessage();
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, io_ex.toString());
                    }
                }
            } catch (RuntimeException rt_ex) {
                if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = RUNTIME_ERROR;
                    setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                    msg = rt_ex.getMessage();
                    if ( _logger.isLoggable(Level.WARNING) ) {
                        _logger.log(Level.WARNING,msg);
                        _logger.log(Level.WARNING, rt_ex.toString());
                    }
                }
            }

            // Derive a Comparable object from the ObservedAttribute value
            // if the type of the ObservedAttribute value is a complex type.
            //
            if (msg == null) {
                try {
                    value = getComparableFromAttribute(object,
                                                       attribute,
                                                       attributeValue);
                } catch (AttributeNotFoundException e) {
                    if (alreadyNotified(index,
                                        OBSERVED_ATTRIBUTE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_ERROR;
                        setAlreadyNotified(index,
                                           OBSERVED_ATTRIBUTE_ERROR_NOTIFIED);
                        msg =
                            "The observed attribute must be accessible in " +
                            "the observed object.";
                        if ( _logger.isLoggable(Level.WARNING) ) {
                            _logger.log(Level.WARNING,msg);
                            _logger.log(Level.WARNING, e.toString());
                        }

                    }
                } catch (RuntimeException e) {
                    if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = RUNTIME_ERROR;
                        setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                        msg = e.getMessage();
                        if ( _logger.isLoggable(Level.WARNING) ) {
                            _logger.log(Level.WARNING,msg);
                            _logger.log(Level.WARNING, e.toString());
                        }
                    }
                }
            }

            // Check that the observed attribute type is supported by this
            // monitor.
            //
            if (msg == null) {
                if (!isComparableTypeValid(object, attribute, value)) {
                    if (alreadyNotified(index,
                                        OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_TYPE_ERROR;
                        setAlreadyNotified(
                                  index,
                                  OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED);
                        msg = "The observed attribute type is not valid.";
                        if ( _logger.isLoggable(Level.WARNING) ) {
                            _logger.log(Level.WARNING,msg);
                        }
                    }
                }
            }

            // Check that threshold type is supported by this monitor.
            //
            if (msg == null) {
                if (!isThresholdTypeValid(object, attribute, value)) {
                    if (alreadyNotified(index, THRESHOLD_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = THRESHOLD_ERROR;
                        setAlreadyNotified(index, THRESHOLD_ERROR_NOTIFIED);
                        msg = "The threshold type is not valid.";
                        if ( _logger.isLoggable(Level.WARNING) ) {
                            _logger.log(Level.WARNING,msg);
                        }
                    }
                }
            }

            // Let someone subclassing the monitor to perform additional
            // monitor consistency checks and report errors if necessary.
            //
            if (msg == null) {
                msg = buildErrorNotification(object, attribute, value);
                if (msg != null) {
                    if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = RUNTIME_ERROR;
                        setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED);
                        if ( _logger.isLoggable(Level.WARNING) ) {
                            _logger.log(Level.WARNING,msg);
                        }
                    }
                }
            }

            // If no errors were found then clear all error flags and
            // let the monitor decide if a notification must be sent.
            //
            if (msg == null) {
                // Clear all already notified flags.
                //
                resetAllAlreadyNotified(index);

                // Get derived gauge from comparable value.
                //
                derGauge = getDerivedGaugeFromComparable(object,
                                                         attribute,
                                                         value);
                derivedGauge[index] = derGauge;
                derivedGaugeTimestamp[index] = System.currentTimeMillis();

                // Check if an alarm must be fired.
                //
                alarm = buildAlarmNotification(object,
                                               attribute,
                                               (Comparable<?>) derGauge);
            }
        }

        // Notify monitor errors
        //
        if (msg != null)
            sendNotification(notifType,
                             System.currentTimeMillis(),
                             msg,
                             derGauge,
                             trigger,
                             object,
                             true);

        // Notify monitor alarms
        //
        if (alarm != null && alarm.getType() != null) {
            sendNotification(alarm.getType(),
                             System.currentTimeMillis(),
                             alarm.getMessage(),
                             derGauge,
                             alarm.getTrigger(),
                             object,
                             false);
        } 
    
voidonErrorNotification(com.sun.appserv.management.event.StatisticMonitorNotification notification)

    
public voidpostDeregister()
Allows the statistic monitor MBean to perform any operations needed after having been unregistered by the MBean server.

Not used in this context.

    
public voidpostRegister(java.lang.Boolean registrationDone)
Allows the statistic monitor MBean to perform any operations needed after having been registered in the MBean server or after the registration has failed.

Not used in this context.

    
public voidpreDeregister()
Allows the statistic monitor MBean to perform any operations it needs before being unregistered by the MBean server.

Stops the statistic monitor.

exception
Exception

        if ( _logger.isLoggable(Level.FINER) )
             _logger.log(Level.FINER,"Stop the statistic monitor");
        // Stop the StatisticMonitor.
        //
        stop();
    
public javax.management.ObjectNamepreRegister(javax.management.MBeanServer server, javax.management.ObjectName name)
Allows the statistic monitor MBean to perform any operations it needs before being registered in the MBean server.

Initializes the reference to the MBean server.

param
server The MBean server in which the statistic monitor MBean will be registered.
param
name The object name of the statistic monitor MBean.
return
The name of the statistic monitor MBean registered.
exception
Exception


    /*
     * ------------------------------------------
     *  PUBLIC METHODS
     * ------------------------------------------
     */

                                                                      
         
          
        if ( _logger.isLoggable(Level.FINER) )
             _logger.log(Level.FINER,"Initialize reference on the MBean Server");
        this.server = server;
        return name;
    
synchronized voidremoveElementAt(int[] array, int index)
Removes the component at the specified index from the specified int array.

        if (index < 0 || index >= elementCount)
            return;
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(array, index + 1, array, index, j);
        }
    
synchronized voidremoveElementAt(long[] array, int index)
Removes the component at the specified index from the specified long array.

        if (index < 0 || index >= elementCount)
            return;
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(array, index + 1, array, index, j);
        }
    
synchronized voidremoveElementAt(boolean[] array, int index)
Removes the component at the specified index from the specified boolean array.

        if (index < 0 || index >= elementCount)
            return;
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(array, index + 1, array, index, j);
        }
    
synchronized voidremoveElementAt(java.lang.Object[] array, int index)
Removes the component at the specified index from the specified Object array.

        if (index < 0 || index >= elementCount)
            return;
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(array, index + 1, array, index, j);
        }
        array[elementCount - 1] = null;
    
public synchronized voidremoveObservedObject(javax.management.ObjectName object)
Removes the specified object from the set of observed MBeans.

param
object The object to remove.
since.unbundled
JMX 1.2

        // Check for null object.
        //
        if (object == null)
            return;

        int index = observedObjects.indexOf(object);
        if (index >= 0) {
            observedObjects.remove(index);
            
            // Update arrays.
            //
            removeElementAt(alreadyNotifieds, index);
            updateDeprecatedAlreadyNotified();
            removeElementAt(derivedGauge, index);
            removeElementAt(derivedGaugeTimestamp, index);
            
            // Update other specific arrays.
            //
            removeSpecificElementAt(index);
            
            // Update elementCount.
            //
            elementCount--;
        }
    
voidremoveSpecificElementAt(int index)
This method is overridden by the specific monitor classes (Counter, Gauge and String). It updates all the specific arrays after removing an observed object from the vector. The method is not abstract so that this class can be subclassed by classes outside this package.

synchronized voidresetAllAlreadyNotified(int index)
Reset all bits in the given element of {@link #alreadyNotifieds}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        alreadyNotifieds[index] = RESET_FLAGS_ALREADY_NOTIFIED;
        if (index == 0)
            updateDeprecatedAlreadyNotified();
    
synchronized voidresetAlreadyNotified(int index, int mask)
Reset the given bits in the given element of {@link #alreadyNotifieds}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        alreadyNotifieds[index] &= ~mask;
        if (index == 0)
            updateDeprecatedAlreadyNotified();
    
private voidsendNotification(java.lang.String type, long timeStamp, java.lang.String msg, java.lang.Object derGauge, java.lang.Object trigger, javax.management.ObjectName object, boolean onError)
This method is used by the monitor MBean to create and send a monitor notification to all the listeners registered for this kind of notification.

param
type The notification type.
param
timeStamp The notification emission date.
param
msg The notification message.
param
derGauge The derived gauge.
param
trigger The threshold/string (depending on the monitor type) that triggered off the notification.
param
object The ObjectName of the observed object that triggered off the notification.
param
onError Flag indicating if this monitor notification is an error notification or an alarm notification.

        if ( _logger.isLoggable(Level.FINER) )
             _logger.log(Level.FINER,"send notification: " +
                  "\n\tNotification observed object = " + object +
                  "\n\tNotification observed attribute = " + observedAttribute +
                  "\n\tNotification derived gauge = " + derGauge);

        long seqno;
        synchronized (this) {
            seqno = sequenceNumber++;
        }

        StatisticMonitorNotification mn =
            new StatisticMonitorNotification(type,
                                    this,
                                    seqno,
                                    timeStamp,
                                    msg,
                                    object,
                                    observedAttribute,
                                    derGauge,
                                    trigger);
        if (onError)
            onErrorNotification(mn);
        sendNotification(mn);
    
synchronized voidsetAlreadyNotified(int index, int mask)
Set the given bits in the given element of {@link #alreadyNotifieds}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        alreadyNotifieds[index] |= mask;
        if (index == 0)
            updateDeprecatedAlreadyNotified();
    
public synchronized voidsetGranularityPeriod(long period)
Sets the granularity period (in milliseconds).
The default value of the granularity period is 10 seconds.

param
period The granularity period value.
exception
IllegalArgumentException The granularity period is less than or equal to zero.
see
#getGranularityPeriod


        if (period <= 0) {
            throw new IllegalArgumentException("Nonpositive granularity " +
                                               "period");
        }
        granularityPeriod = period;
        
        // Reschedule the scheduler task if the statistic monitor is active.
        //
        if (isActive()) {
            schedulerFuture.cancel(false);
            schedulerFuture = scheduler.schedule(schedulerTask,
                                                 period,
                                                 TimeUnit.MILLISECONDS);
        }
    
public voidsetObservedAttribute(java.lang.String attribute)
Sets the attribute to observe.
The observed attribute is not initialized by default (set to null).

param
attribute The attribute to observe.
exception
IllegalArgumentException The specified attribute is null.
see
#getObservedAttribute


        if (attribute == null) {
            throw new IllegalArgumentException("Null observed attribute");
        }

        // Update alreadyNotified array.
        //
        synchronized(this) {
            observedAttribute = attribute;

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            firstAttribute = null;
            remainingAttributes.clear();
            isComplexTypeAttribute = false;

            for (int i = 0; i < elementCount; i++) {
                resetAlreadyNotified(i,
                                     OBSERVED_ATTRIBUTE_ERROR_NOTIFIED |
                                     OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED);
            }
        }
    
public synchronized voidsetObservedObject(javax.management.ObjectName object)
Removes all objects from the set of observed objects, and then adds the specified object.

param
object The object to observe.
exception
IllegalArgumentException The specified object is null.
see
#getObservedObject()
deprecated
As of JMX 1.2, replaced by {@link #addObservedObject}

        while (!observedObjects.isEmpty()) {
            removeObservedObject(observedObjects.get(0));
        }
        addObservedObject(object);
    
public abstract voidstart()
Starts the statistic monitor.

public abstract voidstop()
Stops the statistic monitor.

synchronized voidupdateDeprecatedAlreadyNotified()
Update the deprecated {@link #alreadyNotified} field.

        if (elementCount > 0)
            alreadyNotified = alreadyNotifieds[0];
        else
            alreadyNotified = 0;