FileDocCategorySizeDatePackage
Monitor.javaAPI DocJava SE 6 API56575Tue Jun 10 00:26:16 BST 2008javax.management.monitor

Monitor

public abstract class Monitor extends NotificationBroadcasterSupport implements MonitorMBean, MBeanRegistration
Defines the part common to all monitor MBeans. A 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.
version
4.55 12/29/05
author
Sun Microsystems, Inc
since
1.5

Fields Summary
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 final AtomicLong
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 final 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.
private final MonitorTask
monitorTask
Monitor task to be executed by the Executor Service.
private Future
monitorFuture
Future associated to the current monitor task.
private final SchedulerTask
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.
protected String
dbgTag
This field is retained for compatibility but should not be referenced.
final List
observedObjects
List of ObservedObjects to which the attribute to observe belongs.
static final int
THRESHOLD_ERROR_NOTIFIED
Flag denoting that a notification has occurred after changing the threshold. This flag is used to notify any exception related to invalid thresholds settings.
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 (containsObservedObject(object))
            return;

        // Add the specified object in the list.
        //
        ObservedObject o = createObservedObject(object);
        o.setAlreadyNotified(RESET_FLAGS_ALREADY_NOTIFIED);
        o.setDerivedGauge(null);
        o.setDerivedGaugeTimeStamp(System.currentTimeMillis());
        observedObjects.add(o);

        // Update legacy protected stuff.
        //
        createAlreadyNotified();
    
javax.management.monitor.MonitorNotificationbuildAlarmNotification(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(javax.management.monitor.Monitor$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");
        }
    
private synchronized voidcleanupFutures()
Cleanup the scheduler and monitor tasks futures.

        if (schedulerFuture != null) {
            schedulerFuture.cancel(false);
            schedulerFuture = null;
        }
        if (monitorFuture != null) {
            monitorFuture.cancel(false);
            monitorFuture = null;
        }
    
private synchronized voidcleanupIsComplexTypeAttribute()
Cleanup the "is complex type attribute" info.

        firstAttribute = null;
        remainingAttributes.clear();
        isComplexTypeAttribute = false;
    
synchronized intcomputeAlreadyNotifiedIndex(javax.management.monitor.Monitor$ObservedObject o, int index, int[] an)
Check if the {@link #alreadyNotifieds} array has been modified. If true recompute the index for the given observed object.

        if (an == alreadyNotifieds) {
            return index;
        } else {
            return observedObjects.indexOf(o);
        }
    
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 getObservedObject(object) != null;
    
synchronized voidcreateAlreadyNotified()
Create the {@link #alreadyNotified} array from the {@code ObservedObject} array list.

        // Update elementCount.
        //
        elementCount = observedObjects.size();

        // Update arrays.
        //
        alreadyNotifieds = new int[elementCount];
        for (int i = 0; i < elementCount; i++) {
            alreadyNotifieds[i] = observedObjects.get(i).getAlreadyNotified();
        }
        updateDeprecatedAlreadyNotified();
    
javax.management.monitor.Monitor$ObservedObjectcreateObservedObject(javax.management.ObjectName object)
Factory method for ObservedObject creation.

since
1.6

        return new ObservedObject(object);
    
static voiddebug(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MONITOR, clz, func, info);
    
voiddebug(java.lang.String func, java.lang.String info)

        debug(dbgTag, func, info);
    
voiddoStart()
Starts the monitor.

        if (isTraceOn()) {
            trace("start", "start the monitor");
        }

        synchronized (this) {
            if (isActive()) {
                if (isTraceOn()) {
                    trace("start", "the monitor is already active");
                }
                return;
            }

            isActive = true;

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            cleanupIsComplexTypeAttribute();

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

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

        if (isTraceOn()) {
            trace("stop", "stop the monitor");
        }

        synchronized (this) {
            if (!isActive()) {
                if (isTraceOn()) {
                    trace("stop", "the monitor is not active");
                }
                return;
            }

            isActive = false;

            // Cancel the scheduler task associated with the
            // scheduler and its associated monitor task.
            //
            cleanupFutures();

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

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            cleanupIsComplexTypeAttribute();
        }
    
java.lang.ObjectgetAttribute(javax.management.MBeanServerConnection mbsc, javax.management.ObjectName object, java.lang.String attribute)

        // Check for "ObservedAttribute" replacement.
        // This could happen if a thread A called setObservedAttribute()
        // while other thread B was in the middle of the monitor() method
        // and received the old observed attribute value.
        //
        final boolean lookupMBeanInfo;
        synchronized (this) {
            if (!isActive())
                throw new IllegalArgumentException(
                    "The monitor has been stopped");
            if (!attribute.equals(getObservedAttribute()))
                throw new IllegalArgumentException(
                    "The observed attribute has been changed");
            lookupMBeanInfo =
                (firstAttribute == null && attribute.indexOf('.") != -1);
        }

        // Look up MBeanInfo if needed
        //
        final MBeanInfo mbi;
        if (lookupMBeanInfo) {
            try {
                mbi = mbsc.getMBeanInfo(object);
            } catch (IntrospectionException e) {
                throw new IllegalArgumentException(e);
            }
        } else {
            mbi = null;
        }

        // Check for complex type attribute
        //
        final String fa;
        synchronized (this) {
            if (!isActive())
                throw new IllegalArgumentException(
                    "The monitor has been stopped");
            if (!attribute.equals(getObservedAttribute()))
                throw new IllegalArgumentException(
                    "The observed attribute has been changed");
            if (firstAttribute == null) {
                if (attribute.indexOf('.") != -1) {
                    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;
                }
            }
            fa = firstAttribute;
        }
        return mbsc.getAttribute(object, fa);
    
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
1.6

        final ObservedObject o = getObservedObject(object);
        return o == null ? null : o.getDerivedGauge();
    
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 0 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

        final ObservedObject o = getObservedObject(object);
        return o == null ? 0 : o.getDerivedGaugeTimeStamp();
    
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 synchronized 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;
    
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).getObservedObject();
        }
    
synchronized javax.management.monitor.Monitor$ObservedObjectgetObservedObject(javax.management.ObjectName object)
Get the specified {@code ObservedObject} if this object is contained in the set of observed MBeans, or {@code null} otherwise.

param
object the name of the {@code ObservedObject} to retrieve.
return
The {@code ObservedObject} associated to the supplied {@code ObjectName}.
since
1.6

        for (ObservedObject o : observedObjects)
            if (o.getObservedObject().equals(object))
                return o;
        return null;
    
public synchronized javax.management.ObjectName[]getObservedObjects()
Returns an array containing the objects being observed.

return
The objects being observed.
since.unbundled
JMX 1.2

        ObjectName[] names = new ObjectName[observedObjects.size()];
        for (int i = 0; i < names.length; i++)
            names[i] = observedObjects.get(i).getObservedObject();
        return names;
    
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 EnvHelp.initCause(
                new AttributeNotFoundException(e.getMessage()), e);
        }
    
public synchronized booleanisActive()
Tests whether the monitor MBean is active. A 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 monitor MBean is active, false otherwise.

        return isActive;
    
synchronized booleanisAlreadyNotified(javax.management.monitor.Monitor$ObservedObject o, int mask)
Check if the given bits in the given element of {@link #alreadyNotifieds} are set.

        return ((o.getAlreadyNotified() & mask) != 0);
    
booleanisComparableTypeValid(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return true;
    
static booleanisDebugOn()

        return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MONITOR);
    
booleanisThresholdTypeValid(javax.management.ObjectName object, java.lang.String attribute, java.lang.Comparable value)

        return true;
    
static booleanisTraceOn()


    // TRACES & DEBUG
    //---------------

       
        return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MONITOR);
    
static booleanisValidForType(java.lang.Object value, java.lang.Class c)

        return ((value == INTEGER_ZERO) || c.isInstance(value));
    
private voidmonitor(javax.management.monitor.Monitor$ObservedObject o, int index, int[] an)
This method is called by the monitor each time the granularity period has been exceeded.

param
o The observed object.


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

        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.
        //
        synchronized (this) {
            object = o.getObservedObject();
            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 (isAlreadyNotified(
                        o, OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
                    return;
                else {
                    notifType = OBSERVED_ATTRIBUTE_TYPE_ERROR;
                    setAlreadyNotified(
                        o, index, OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED, an);
                    msg = "The observed attribute value is null.";
                    if (isDebugOn()) {
                        debug("monitor", msg);
                    }
                }
        } catch (NullPointerException np_ex) {
            if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                return;
            else {
                notifType = RUNTIME_ERROR;
                setAlreadyNotified(o, index, RUNTIME_ERROR_NOTIFIED, an);
                msg =
                    "The monitor must be registered in the MBean " +
                    "server or an MBeanServerConnection must be " +
                    "explicitly supplied.";
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", np_ex.toString());
                }
            }
        } catch (InstanceNotFoundException inf_ex) {
            if (isAlreadyNotified(o, OBSERVED_OBJECT_ERROR_NOTIFIED))
                return;
            else {
                notifType = OBSERVED_OBJECT_ERROR;
                setAlreadyNotified(
                    o, index, OBSERVED_OBJECT_ERROR_NOTIFIED, an);
                msg =
                    "The observed object must be accessible in " +
                    "the MBeanServerConnection.";
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", inf_ex.toString());
                }
            }
        } catch (AttributeNotFoundException anf_ex) {
            if (isAlreadyNotified(o, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED))
                return;
            else {
                notifType = OBSERVED_ATTRIBUTE_ERROR;
                setAlreadyNotified(
                    o, index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED, an);
                msg =
                    "The observed attribute must be accessible in " +
                    "the observed object.";
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", anf_ex.toString());
                }
            }
        } catch (MBeanException mb_ex) {
            if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                return;
            else {
                notifType = RUNTIME_ERROR;
                setAlreadyNotified(o, index, RUNTIME_ERROR_NOTIFIED, an);
                msg = mb_ex.getMessage() == null ? "" : mb_ex.getMessage();
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", mb_ex.toString());
                }
            }
        } catch (ReflectionException ref_ex) {
            if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED)) {
                return;
            } else {
                notifType = RUNTIME_ERROR;
                setAlreadyNotified(o, index, RUNTIME_ERROR_NOTIFIED, an);
                msg = ref_ex.getMessage() == null ? "" : ref_ex.getMessage();
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", ref_ex.toString());
                }
            }
        } catch (IOException io_ex) {
            if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                return;
            else {
                notifType = RUNTIME_ERROR;
                setAlreadyNotified(o, index, RUNTIME_ERROR_NOTIFIED, an);
                msg = io_ex.getMessage() == null ? "" : io_ex.getMessage();
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", io_ex.toString());
                }
            }
        } catch (RuntimeException rt_ex) {
            if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                return;
            else {
                notifType = RUNTIME_ERROR;
                setAlreadyNotified(o, index, RUNTIME_ERROR_NOTIFIED, an);
                msg = rt_ex.getMessage() == null ? "" : rt_ex.getMessage();
                if (isDebugOn()) {
                    debug("monitor", msg);
                    debug("monitor", rt_ex.toString());
                }
            }
        }

        synchronized (this) {

            // Check if the monitor has been stopped.
            //
            if (!isActive())
                return;

            // Check if the observed attribute has been changed.
            //
            // Avoid race condition where mbs.getAttribute() succeeded but
            // another thread replaced the observed attribute meanwhile.
            //
            // Avoid setting computed derived gauge on erroneous attribute.
            //
            if (!attribute.equals(getObservedAttribute()))
                return;

            // 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 (ClassCastException e) {
                    if (isAlreadyNotified(
                            o, OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_TYPE_ERROR;
                        setAlreadyNotified(o, index,
                            OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED, an);
                        msg =
                            "The observed attribute value does not " +
                            "implement the Comparable interface.";
                        if (isDebugOn()) {
                            debug("monitor", msg);
                            debug("monitor", e.toString());
                        }
                    }
                } catch (AttributeNotFoundException e) {
                    if (isAlreadyNotified(o, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_ERROR;
                        setAlreadyNotified(
                            o, index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED, an);
                        msg =
                            "The observed attribute must be accessible in " +
                            "the observed object.";
                        if (isDebugOn()) {
                            debug("monitor", msg);
                            debug("monitor", e.toString());
                        }
                    }
                } catch (RuntimeException e) {
                    if (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = RUNTIME_ERROR;
                        setAlreadyNotified(o, index,
                            RUNTIME_ERROR_NOTIFIED, an);
                        msg = e.getMessage() == null ? "" : e.getMessage();
                        if (isDebugOn()) {
                            debug("monitor", msg);
                            debug("monitor", e.toString());
                        }
                    }
                }
            }

            // Check that the observed attribute type is supported by this
            // monitor.
            //
            if (msg == null) {
                if (!isComparableTypeValid(object, attribute, value)) {
                    if (isAlreadyNotified(
                            o, OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = OBSERVED_ATTRIBUTE_TYPE_ERROR;
                        setAlreadyNotified(o, index,
                            OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED, an);
                        msg = "The observed attribute type is not valid.";
                        if (isDebugOn()) {
                            debug("monitor", msg);
                        }
                    }
                }
            }

            // Check that threshold type is supported by this monitor.
            //
            if (msg == null) {
                if (!isThresholdTypeValid(object, attribute, value)) {
                    if (isAlreadyNotified(o, THRESHOLD_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = THRESHOLD_ERROR;
                        setAlreadyNotified(o, index,
                            THRESHOLD_ERROR_NOTIFIED, an);
                        msg = "The threshold type is not valid.";
                        if (isDebugOn()) {
                            debug("monitor", 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 (isAlreadyNotified(o, RUNTIME_ERROR_NOTIFIED))
                        return;
                    else {
                        notifType = RUNTIME_ERROR;
                        setAlreadyNotified(o, index,
                            RUNTIME_ERROR_NOTIFIED, an);
                        if (isDebugOn()) {
                            debug("monitor", 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(o, index, an);

                // Get derived gauge from comparable value.
                //
                derGauge = getDerivedGaugeFromComparable(object,
                                                         attribute,
                                                         value);

                o.setDerivedGauge(derGauge);
                o.setDerivedGaugeTimeStamp(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(javax.management.monitor.MonitorNotification notification)

    
public voidpostDeregister()
Allows the 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 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 monitor MBean to perform any operations it needs before being unregistered by the MBean server.

Stops the monitor.

exception
Exception


        if (isTraceOn()) {
            trace("preDeregister", "stop the monitor");
        }

        // Stop the Monitor.
        //
        stop();
    
public javax.management.ObjectNamepreRegister(javax.management.MBeanServer server, javax.management.ObjectName name)
Allows the 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 monitor MBean will be registered.
param
name The object name of the monitor MBean.
return
The name of the monitor MBean registered.
exception
Exception


        if (isTraceOn()) {
            trace("preRegister",
                  "initialize the reference on the MBean server");
        }

        this.server = server;
        return name;
    
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;

        final ObservedObject o = getObservedObject(object);
        if (o != null) {
            // Remove the specified object from the list.
            //
            observedObjects.remove(o);
            // Update legacy protected stuff.
            //
            createAlreadyNotified();
        }
    
synchronized voidresetAllAlreadyNotified(javax.management.monitor.Monitor$ObservedObject o, int index, int[] an)
Reset all bits in the given element of {@link #alreadyNotifieds}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        final int i = computeAlreadyNotifiedIndex(o, index, an);
        if (i == -1)
            return;
        o.setAlreadyNotified(RESET_FLAGS_ALREADY_NOTIFIED);
        updateAlreadyNotified(o, index);
    
synchronized voidresetAlreadyNotified(javax.management.monitor.Monitor$ObservedObject o, 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.

        o.setAlreadyNotified(o.getAlreadyNotified() & ~mask);
        updateAlreadyNotified(o, index);
    
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 (!isActive())
            return;

        if (isTraceOn())
            trace("sendNotification", "send notification: " +
                  "\n\tNotification observed object = " + object +
                  "\n\tNotification observed attribute = " + observedAttribute +
                  "\n\tNotification derived gauge = " + derGauge);

        long seqno = sequenceNumber.getAndIncrement();

        MonitorNotification mn =
            new MonitorNotification(type,
                                    this,
                                    seqno,
                                    timeStamp,
                                    msg,
                                    object,
                                    observedAttribute,
                                    derGauge,
                                    trigger);
        if (onError)
            onErrorNotification(mn);
        sendNotification(mn);
    
synchronized voidsetAlreadyNotified(javax.management.monitor.Monitor$ObservedObject o, int index, int mask, int[] an)
Set the given bits in the given element of {@link #alreadyNotifieds}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        final int i = computeAlreadyNotifiedIndex(o, index, an);
        if (i == -1)
            return;
        o.setAlreadyNotified(o.getAlreadyNotified() | mask);
        updateAlreadyNotified(o, i);
    
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");
        }

        if (granularityPeriod == period)
            return;
        granularityPeriod = period;

        // Reschedule the scheduler task if the monitor is active.
        //
        if (isActive()) {
            cleanupFutures();
            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) {
            if (observedAttribute != null &&
                observedAttribute.equals(attribute))
                return;
            observedAttribute = attribute;

            // Reset the complex type attribute information
            // such that it is recalculated again.
            //
            cleanupIsComplexTypeAttribute();

            int index = 0;
            for (ObservedObject o : observedObjects) {
                resetAlreadyNotified(o, index++,
                                     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}

        if (object == null)
            throw new IllegalArgumentException("Null observed object");
        if (observedObjects.size() == 1 && containsObservedObject(object))
            return;
        observedObjects.clear();
        addObservedObject(object);
    
public abstract voidstart()
Starts the monitor.

public abstract voidstop()
Stops the monitor.

static voidtrace(java.lang.String clz, java.lang.String func, java.lang.String info)

        Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MONITOR, clz, func, info);
    
voidtrace(java.lang.String func, java.lang.String info)

        trace(dbgTag, func, info);
    
synchronized voidupdateAlreadyNotified(javax.management.monitor.Monitor$ObservedObject o, int index)
Update the {@link #alreadyNotifieds} array element at the given index with the already notified flag in the given {@code ObservedObject}. Ensure the deprecated {@link #alreadyNotified} field is updated if appropriate.

        alreadyNotifieds[index] = o.getAlreadyNotified();
        if (index == 0)
            updateDeprecatedAlreadyNotified();
    
synchronized voidupdateDeprecatedAlreadyNotified()
Update the deprecated {@link #alreadyNotified} field.

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