User: ejort   
  Date: 01/12/20 17:39:37

  Added:       src/main/javax/management/monitor CounterMonitor.java
                        CounterMonitorMBean.java GaugeMonitor.java
                        GaugeMonitorMBean.java Monitor.java
                        MonitorMBean.java MonitorNotification.java
                        MonitorSettingException.java StringMonitor.java
                        StringMonitorMBean.java package.html
  Log:
  Initial version of the monitor services.
  Not fully tested. Basic functionality works.
  The spec/javadoc is either very vague or wrong compared to RI in this package.
  Compatibilty tests to follow later.
  
  Revision  Changes    Path
  1.1                  jmx/src/main/javax/management/monitor/CounterMonitor.java
  
  Index: CounterMonitor.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanNotificationInfo;
  
  // REVIEW: Check synchronization
  
  /**
   * The counter monitor service.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public class CounterMonitor
    extends Monitor
    implements CounterMonitorMBean
  {
    // Constants -----------------------------------------------------
  
    /**
     * The counter threshold exceeded has been notified.
     */
    int THRESHOLD_EXCEEDED_NOTIFIED = 16;
  
    /**
     * The threshold type error has been notified.
     */
    int THRESHOLD_ERROR_NOTIFIED = 32;
  
    // Attributes ----------------------------------------------------
  
    /**
     * The derived gauge.
     */
    private Number derivedGauge = new Integer(0);
  
    /**
     * The last value.
     */
    private Number lastValue = null;
  
    /**
     * The derived gauge timeStamp.
     */
    private long derivedGaugeTimeStamp = 0;
  
    /**
     * The offset.
     */
    Number offset = new Integer(0);
  
    /**
     * The modulus.
     */
    Number modulus = new Integer(0);
  
    /**
     * The threshold.
     */
    Number threshold = new Integer(0);
  
    /**
     * The last stated threshold.
     */
    Number lastThreshold = new Integer(0);
  
    /**
     * Difference mode.
     */
    boolean differenceMode = false;
  
    /**
     * Notify.
     */
    boolean notify = false;
  
    // Static --------------------------------------------------------
  
    // Constructors --------------------------------------------------
  
    /**
     * Default Constructor
     */
    public CounterMonitor()
    {
      dbgTag = "CounterMonitor";
    }
  
    // Public --------------------------------------------------------
  
    public MBeanNotificationInfo[] getNotificationInfo()
    {
      MBeanNotificationInfo[] result = new MBeanNotificationInfo[1];
      String[] types = new String[]
      {
        MonitorNotification.RUNTIME_ERROR,
        MonitorNotification.OBSERVED_OBJECT_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
        MonitorNotification.THRESHOLD_ERROR,
        MonitorNotification.THRESHOLD_VALUE_EXCEEDED
      };
      result[0] = new MBeanNotificationInfo(types,
        "javax.management.monitor.MonitorNotification",
        "Notifications sent by the Counter Monitor Service MBean");
      return result;
    }
  
    // CounterMonitorMBean implementation ----------------------------
  
    public Number getDerivedGauge()
    {
      return derivedGauge;
    }
  
    public long getDerivedGaugeTimeStamp()
    {
      return derivedGaugeTimeStamp;
    }
  
    public boolean getDifferenceMode()
    {
      return differenceMode;
    }
  
    public void setDifferenceMode(boolean value)
    {
      differenceMode = value;
    }
  
    public Number getModulus()
    {
      return modulus;
    }
  
    public void setModulus(Number value)
      throws IllegalArgumentException
    {
      if (value == null)
        throw new IllegalArgumentException("Null modulus");
      if (value.longValue() < 0)
        throw new IllegalArgumentException("Negative modulus");
      modulus = value;
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    public boolean getNotify()
    {
      return notify;
    }
  
    public void setNotify(boolean value)
    {
      notify = value;
    }
  
    public Number getOffset()
    {
      return offset;
    }
  
    public void setOffset(Number value)
      throws IllegalArgumentException
    {
      if (value == null)
        throw new IllegalArgumentException("Null offset");
      if (value.longValue() < 0)
        throw new IllegalArgumentException("Negative offset");
      offset = value;
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    public Number getThreshold()
    {
      return threshold;
    }
  
    public void setThreshold(Number value)
      throws IllegalArgumentException
    {
      if (value == null)
        throw new IllegalArgumentException("Null threshold");
      if (value.longValue() < 0)
        throw new IllegalArgumentException("Negative threshold");
      threshold = value;
      lastThreshold = value;
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    // Override start to reset the last value for difference mode and
    // to get the initial gauge.
    public synchronized void start()
    {
      lastValue = null;
      derivedGauge = new Integer(0);
      derivedGaugeTimeStamp = System.currentTimeMillis();
      super.start();
    }
  
    // Package protected ---------------------------------------------
  
    // REVIEW: This works but needs tidying up!
    void monitor(MBeanAttributeInfo attributeInfo, Object value)
      throws Exception
    {
      // Wrong type of attribute
      if (!(value instanceof Byte) && !(value instanceof Integer) &&
          !(value instanceof Short) && !(value instanceof Long))
      {
         sendAttributeTypeErrorNotification("Attribute is not an integer type");
         return;
      }
  
      // Wrong threshold types
      if (threshold.getClass() != value.getClass()
          || offset.longValue() != 0 && offset.getClass() != value.getClass()
          || modulus.longValue() != 0 && modulus.getClass() != value.getClass()) 
      {
         sendThresholdErrorNotification(value);
         return;
      }
  
      // Cast the counter to a Number
      Number number = (Number) value;
  
      // Get the gauge and record when we got it.
      if (differenceMode)
      {
        if (lastValue == null)
          derivedGauge = getZero(number);
        else
          derivedGauge = sub(number, lastValue);
        if (derivedGauge.longValue() < 0 && modulus.longValue() != 0)
          derivedGauge = add(derivedGauge, modulus);
      }
      else
        derivedGauge = number;
      derivedGaugeTimeStamp = System.currentTimeMillis();
  
      // Fire the event if the threshold has been exceeded
      if (derivedGauge.longValue() >= threshold.longValue())
      {
        if ((alreadyNotified & THRESHOLD_EXCEEDED_NOTIFIED) == 0)
        {
          sendThresholdExceededNotification(derivedGauge);
          alreadyNotified |= THRESHOLD_EXCEEDED_NOTIFIED;
  
          // Add any offsets required to get a new threshold
          if (offset.longValue() != 0)
          {
            while(threshold.longValue() <= derivedGauge.longValue())
              threshold = add(threshold, offset);
            alreadyNotified &= ~THRESHOLD_EXCEEDED_NOTIFIED;
          }
        }
      }
      else
      {
        // Reset notfication when it becomes less than threshold
        if (derivedGauge.longValue() < threshold.longValue())
          alreadyNotified &= ~THRESHOLD_EXCEEDED_NOTIFIED;
      }
  
      // Apply any modulus, reset the threshold
      // REVIEW: This is not what the spec does, its what the RI does
      if (modulus.longValue() != 0 && lastValue !=null 
          && lastValue.longValue() > number.longValue())
      {
        threshold = lastThreshold;
        alreadyNotified &= ~THRESHOLD_EXCEEDED_NOTIFIED;
      }
  
      // Remember the last value
      lastValue = number;
    }
  
    /**
     * Get zero for the type passed.
     * 
     * @param the reference object
     * @return zero for the correct type
     */
    Number getZero(Number value)
    {
       if (value instanceof Byte)
         return new Byte((byte) 0);
       if (value instanceof Integer)
         return new Integer(0);
       if (value instanceof Short)
         return new Short((short) 0);
       return new Long(0);
    }
  
    /**
     * Add two numbers together.
     * @param value1 the first value.
     * @param value2 the second value.
     * @return value1 + value2 of the correct type
     */
    Number add(Number value1, Number value2)
    {
       if (value1 instanceof Byte)
         return new Byte((byte) (value1.byteValue() + value2.byteValue()));
       if (value1 instanceof Integer)
         return new Integer(value1.intValue() + value2.intValue());
       if (value1 instanceof Short)
         return new Short((short) (value1.shortValue() + value2.shortValue()));
       return new Long(value1.longValue() + value2.longValue());
    }
  
    /**
     * Subtract two numbers.
     * @param value1 the first value.
     * @param value2 the second value.
     * @return value1 - value2 of the correct type
     */
    Number sub(Number value1, Number value2)
    {
       if (value1 instanceof Byte)
         return new Byte((byte) (value1.byteValue() - value2.byteValue()));
       if (value1 instanceof Integer)
         return new Integer(value1.intValue() - value2.intValue());
       if (value1 instanceof Short)
         return new Short((short) (value1.shortValue() - value2.shortValue()));
       return new Long(value1.longValue() - value2.longValue());
    }
  
    /**
     * Send a threshold exceeded event.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendThresholdExceededNotification(Object value)
    {
      if (notify)
      {
        sendNotification(MonitorNotification.THRESHOLD_VALUE_EXCEEDED,
          derivedGaugeTimeStamp, "threshold exceeded", observedAttribute, value, 
          threshold);
      }
    }
  
    /**
     * Send a threshold error event.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendThresholdErrorNotification(Object value)
    {
      if ((alreadyNotified & THRESHOLD_ERROR_NOTIFIED) == 0)
      {
        sendNotification(MonitorNotification.THRESHOLD_ERROR,
          derivedGaugeTimeStamp, 
          "Threshold, offset or modulus not the correct type", 
          observedAttribute, null, null);
        alreadyNotified |= THRESHOLD_ERROR_NOTIFIED;
      }
    }
  
    // Protected -----------------------------------------------------
  
    // Private -------------------------------------------------------
  
    // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/CounterMonitorMBean.java
  
  Index: CounterMonitorMBean.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  /**
   * The counter monitor service MBean interface. <p>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public interface CounterMonitorMBean
    extends MonitorMBean
  {
    // Constants -----------------------------------------------------
    
    // Static --------------------------------------------------------
    
    // Public --------------------------------------------------------
  
    /**
     * Retrieves the derived gauge.
     *
     * @return the derived gauge.
     */
    public Number getDerivedGauge();
  
    /**
     * Retrieves the derived gauge timestamp.
     *
     * @return the derived gauge timestamp.
     */
    public long getDerivedGaugeTimeStamp();
  
    /**
     * Retrieves the difference mode flag.
     *
     * @return true when in difference mode, false otherwise.
     */
    public boolean getDifferenceMode();
  
    /**
     * Sets the difference mode flag.
     *
     * @return value pass true for difference mode, false otherwise.
     */
    public void setDifferenceMode(boolean value);
  
    /**
     * Retrieves the modulus.
     *
     * @return the modulus value, zero means no modulus.
     */
    public Number getModulus();
  
    /**
     * Sets the modulus.
     *
     * @param value the modulus value, pass zero for no modulus.
     * @exception IllegalArgumentException when the modulus is null or 
     *        less than zero.
     */
    public void setModulus(Number value)
      throws IllegalArgumentException;
  
    /**
     * Retrieves the notify on/off switch.
     *
     * @return true if notifications occur, false otherwise.
     */
    public boolean getNotify();
  
    /**
     * Sets the notify on/off switch.
     *
     * @param value pass true notifications, false otherwise.
     */
    public void setNotify(boolean value);
  
    /**
     * Retrieves the offset.
     *
     * @return the offset value, zero means no offset.
     */
    public Number getOffset();
  
    /**
     * Sets the offset.
     *
     * @param value the offset value, pass zero for no offset.
     * @exception IllegalArgumentException when the offset is null or 
     *        less than zero.
     */
    public void setOffset(Number value)
      throws IllegalArgumentException;
  
    /**
     * Retrieves the threshold.
     * REVIEW: zero threshold
     *
     * @return the threshold value, zero means no threshold.
     */
    public Number getThreshold();
  
    /**
     * Sets the threshold.
     * REVIEW: zero threshold
     *
     * @param value the threshold value, pass zero for no threshold.
     * @exception IllegalArgumentException when the threshold is null or 
     *        less than zero.
     */
    public void setThreshold(Number value)
      throws IllegalArgumentException;
  }
  
  
  1.1                  jmx/src/main/javax/management/monitor/GaugeMonitor.java
  
  Index: GaugeMonitor.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanNotificationInfo;
  
  // REVIEW: Check synchronization
  
  /**
   * The gauge monitor service.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public class GaugeMonitor
    extends Monitor
    implements GaugeMonitorMBean
  {
    // Constants -----------------------------------------------------
  
    /**
     * The gauge high threshold exceeded has been notified.
     */
    int THRESHOLD_HIGH_EXCEEDED_NOTIFIED = 16;
  
    /**
     * The gauge low threshold exceeded has been notified.
     */
    int THRESHOLD_LOW_EXCEEDED_NOTIFIED = 32;
  
    /**
     * The threshold type error has been notified.
     */
    int THRESHOLD_ERROR_NOTIFIED = 64;
  
    // Attributes ----------------------------------------------------
  
    /**
     * The derived gauge.
     */
    private Number derivedGauge = new Integer(0);
  
    /**
     * The last value.
     */
    private Number lastValue = null;
  
    /**
     * The derived gauge timeStamp.
     */
    private long derivedGaugeTimeStamp = 0;
  
    /**
     * Difference mode.
     */
    boolean differenceMode = false;
  
    /**
     * The high threshold.
     */
    Number highThreshold = new Integer(0);
  
    /**
     * The low threshold.
     */
    Number lowThreshold = new Integer(0);
  
    /**
     * High Notify.
     */
    boolean notifyHigh = false;
  
    /**
     * Low Notify.
     */
    boolean notifyLow = false;
  
    // Static --------------------------------------------------------
  
    // Constructors --------------------------------------------------
  
    /**
     * Default Constructor
     */
    public GaugeMonitor()
    {
      dbgTag = "GaugeMonitor";
    }
  
    // Public --------------------------------------------------------
  
    public MBeanNotificationInfo[] getNotificationInfo()
    {
      MBeanNotificationInfo[] result = new MBeanNotificationInfo[1];
      String[] types = new String[]
      {
        MonitorNotification.RUNTIME_ERROR,
        MonitorNotification.OBSERVED_OBJECT_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
        MonitorNotification.THRESHOLD_ERROR,
        MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED,
        MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED
      };
      result[0] = new MBeanNotificationInfo(types,
        "javax.management.monitor.MonitorNotification",
        "Notifications sent by the Gauge Monitor Service MBean");
      return result;
    }
  
    // GaugeMonitorMBean implementation ------------------------------
  
    public Number getDerivedGauge()
    {
      return derivedGauge;
    }
  
    public long getDerivedGaugeTimeStamp()
    {
      return derivedGaugeTimeStamp;
    }
  
    public boolean getDifferenceMode()
    {
      return differenceMode;
    }
  
    public void setDifferenceMode(boolean value)
    {
      differenceMode = value;
    }
  
    public boolean getNotifyHigh()
    {
      return notifyHigh;
    }
  
    public void setNotifyHigh(boolean value)
    {
      notifyHigh = value;
    }
  
    public boolean getNotifyLow()
    {
      return notifyLow;
    }
  
    public void setNotifyLow(boolean value)
    {
      notifyLow = value;
    }
  
    public Number getHighThreshold()
    {
      return highThreshold;
    }
  
    public Number getLowThreshold()
    {
      return lowThreshold;
    }
  
    public void setThresholds(Number highValue, Number lowValue)
      throws IllegalArgumentException
    {
      if (highValue == null)
        throw new IllegalArgumentException("Null high threshold");
      if (lowValue == null)
        throw new IllegalArgumentException("Null low threshold");
      if (highValue.getClass() != lowValue.getClass())
        throw new IllegalArgumentException("High and low different types");
      if (highValue.doubleValue() < lowValue.doubleValue())
        throw new IllegalArgumentException("High less than low threshold");
      highThreshold = highValue;
      lowThreshold = lowValue;
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    // Override start to reset the last value for difference mode and
    // to get the initial gauge.
    public synchronized void start()
    {
      lastValue = null;
      derivedGauge = new Integer(0);
      derivedGaugeTimeStamp = System.currentTimeMillis();
      super.start();
    }
  
    // Package protected ---------------------------------------------
  
    // REVIEW: This works but needs tidying up!
    void monitor(MBeanAttributeInfo attributeInfo, Object value)
      throws Exception
    {
      // Wrong type of attribute
      if (!(value instanceof Number))
      {
         sendAttributeTypeErrorNotification("Attribute is not a number");
         return;
      }
  
      // Wrong threshold types
      if (highThreshold.getClass() != value.getClass()
          || lowThreshold.getClass() != value.getClass())
      {
         sendThresholdErrorNotification(value);
         return;
      }
  
      // Cast the gauge to a Number
      Number number = (Number) value;
  
      // Get the gauge and record when we got it.
      if (differenceMode)
      {
        if (lastValue == null)
          derivedGauge = getZero(number);
        else
          derivedGauge = sub(number, lastValue);
      }
      else
        derivedGauge = number;
      derivedGaugeTimeStamp = System.currentTimeMillis();
  
      // Fire the event if the low threshold has been exceeded
      if (derivedGauge.doubleValue() <= lowThreshold.doubleValue())
      {
        if ((alreadyNotified & THRESHOLD_LOW_EXCEEDED_NOTIFIED) == 0)
        {
          sendThresholdLowExceededNotification(derivedGauge);
          alreadyNotified |= THRESHOLD_LOW_EXCEEDED_NOTIFIED;
        }
      }
      else
      {
        // Reset notfication when it becomes higher than low threshold
        if (derivedGauge.doubleValue() > lowThreshold.doubleValue())
          alreadyNotified &= ~THRESHOLD_LOW_EXCEEDED_NOTIFIED;
      }
  
      // Fire the event if the high threshold has been exceeded
      if (derivedGauge.doubleValue() >= highThreshold.doubleValue())
      {
        if ((alreadyNotified & THRESHOLD_HIGH_EXCEEDED_NOTIFIED) == 0)
        {
          sendThresholdHighExceededNotification(derivedGauge);
          alreadyNotified |= THRESHOLD_HIGH_EXCEEDED_NOTIFIED;
        }
      }
      else
      {
        // Reset notfication when it becomes less than high threshold
        if (derivedGauge.doubleValue() < highThreshold.doubleValue())
          alreadyNotified &= ~THRESHOLD_HIGH_EXCEEDED_NOTIFIED;
      }
  
      // Remember the last value
      lastValue = number;
    }
  
    /**
     * Get zero for the type passed.
     * 
     * @param the reference object
     * @return zero for the correct type
     */
    Number getZero(Number value)
    {
       if (value instanceof Byte)
         return new Byte((byte) 0);
       if (value instanceof Integer)
         return new Integer(0);
       if (value instanceof Long)
         return new Long(0);
       if (value instanceof Short)
         return new Short((short) 0);
       if (value instanceof Float)
         return new Float((float) 0);
       return new Double((double) 0);
    }
  
    /**
     * Subtract two numbers.
     * @param value1 the first value.
     * @param value2 the second value.
     * @return value1 - value2 of the correct type
     */
    Number sub(Number value1, Number value2)
    {
       if (value1 instanceof Byte)
         return new Byte((byte) (value1.byteValue() - value2.byteValue()));
       if (value1 instanceof Integer)
         return new Integer(value1.intValue() - value2.intValue());
       if (value1 instanceof Long)
         return new Long((value1.longValue() - value2.longValue()));
       if (value1 instanceof Short)
         return new Short((short) (value1.shortValue() - value2.shortValue()));
       if (value1 instanceof Float)
         return new Float((value1.floatValue() - value2.floatValue()));
       return new Double(value1.doubleValue() - value2.doubleValue());
    }
  
    /**
     * Send a threshold low exceeded event.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendThresholdLowExceededNotification(Object value)
    {
      if (notifyLow)
      {
        sendNotification(MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED,
          derivedGaugeTimeStamp, "low threshold exceeded", observedAttribute, 
          value, lowThreshold);
      }
    }
  
    /**
     * Send a high threshold exceeded event.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendThresholdHighExceededNotification(Object value)
    {
      if (notifyHigh)
      {
        sendNotification(MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED,
          derivedGaugeTimeStamp, "high threshold exceeded", observedAttribute, 
          value, highThreshold);
      }
    }
  
    /**
     * Send a threshold error event.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendThresholdErrorNotification(Object value)
    {
      if ((alreadyNotified & THRESHOLD_ERROR_NOTIFIED) == 0)
      {
        sendNotification(MonitorNotification.THRESHOLD_ERROR,
          derivedGaugeTimeStamp, 
          "High or Low Threshold not the correct type", 
          observedAttribute, null, null);
        alreadyNotified |= THRESHOLD_ERROR_NOTIFIED;
      }
    }
  
    // Protected -----------------------------------------------------
  
    // Private -------------------------------------------------------
  
    // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/GaugeMonitorMBean.java
  
  Index: GaugeMonitorMBean.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  /**
   * The gauge monitor service MBean interface. <p>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public interface GaugeMonitorMBean
    extends MonitorMBean
  {
    // Constants -----------------------------------------------------
    
    // Static --------------------------------------------------------
    
    // Public --------------------------------------------------------
  
    /**
     * Retrieves the derived gauge.
     *
     * @return the derived gauge.
     */
    public Number getDerivedGauge();
  
    /**
     * Retrieves the derived gauge timestamp.
     *
     * @return the derived gauge timestamp.
     */
    public long getDerivedGaugeTimeStamp();
  
    /**
     * Retrieves the difference mode flag.
     *
     * @return true when in difference mode, false otherwise.
     */
    public boolean getDifferenceMode();
  
    /**
     * Sets the difference mode flag.
     *
     * @return value pass true for difference mode, false otherwise.
     */
    public void setDifferenceMode(boolean value);
  
    /**
     * Retrieves the high notify on/off switch.
     *
     * @return true if high notifications occur, false otherwise.
     */
    public boolean getNotifyHigh();
  
    /**
     * Sets the high notify on/off switch.
     *
     * @param value pass true for high notifications, false otherwise.
     */
    public void setNotifyHigh(boolean value);
  
    /**
     * Retrieves the low notify on/off switch.
     *
     * @return true if low notifications occur, false otherwise.
     */
    public boolean getNotifyLow();
  
    /**
     * Sets the low notify on/off switch.
     *
     * @param value pass true for low notifications, false otherwise.
     */
    public void setNotifyLow(boolean value);
  
    /**
     * Retrieves the high threshold.
     * REVIEW: zero threshold
     *
     * @return the high threshold value, zero means no threshold.
     */
    public Number getHighThreshold();
  
    /**
     * Retrieves the low threshold.
     * REVIEW: zero threshold
     *
     * @return the low threshold value, zero means no threshold.
     */
    public Number getLowThreshold();
  
    /**
     * Sets the high and low threshold.
     * REVIEW: zero threshold
     *
     * @param highValue the high threshold value, pass zero for no high 
     *        threshold.
     * @param lowValue the low threshold value, pass zero for no low
     *        threshold.
     * @exception IllegalArgumentException when either threshold is null or 
     *        the high threshold is lower than the low threshold or the.
     *        thresholds have different types.
     */
    public void setThresholds(Number highValue, Number lowValue)
      throws IllegalArgumentException;
  }
  
  
  1.1                  jmx/src/main/javax/management/monitor/Monitor.java
  
  Index: Monitor.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import java.io.Serializable;
  
  import javax.management.InstanceNotFoundException;
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanInfo;
  import javax.management.MBeanRegistration;
  import javax.management.MBeanServer;
  import javax.management.NotificationBroadcasterSupport;
  import javax.management.ObjectName;
  
  // REVIEW: Check synchronization
  
  /**
   * The monitor service.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public abstract class Monitor
    extends NotificationBroadcasterSupport
    implements MonitorMBean, MBeanRegistration, Serializable
  {
    // Constants -----------------------------------------------------
  
    /**
     * Used to reset errors in {@link #alreadyNotified}.
     * REVIEW: Check
     */
    protected final int RESET_FLAGS_ALREADY_NOTIFIED = 0;
  
    /**
     * An observed attribute type error has been notified.
     * REVIEW: Check
     */
    protected final int RUNTIME_ERROR_NOTIFIED = 1;
  
    /**
     * An observed object error has been notified.
     * REVIEW: Check
     */
    protected final int OBSERVED_OBJECT_ERROR_NOTIFIED = 2;
  
    /**
     * An observed attribute error has been notified.
     * REVIEW: Check
     */
    protected final int OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 4;
  
    /**
     * An observed attribute type error has been notified.
     * REVIEW: Check
     */
    protected final int OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 8;
  
    // Attributes ----------------------------------------------------
  
    /**
     * The granularity period.
     */
    long granularityPeriod = 10000;
  
    /**
     * The observed attribute.
     */
    String observedAttribute = null;
  
    /**
     * The observed object.
     */
    ObjectName observedObject = null;
  
    /**
     * Whether the service is active.
     */
    boolean active = false;
  
    /**
     * The server this service is registered in.
     */
    protected MBeanServer server;
  
    /**
     * The errors that have already been notified.
     * REVIEW: Check
     */
    protected int alreadyNotified = 0;
  
    /**
     * ????.
     * REVIEW: Implement
     */
    protected String dbgTag = null;
  
    /**
     * The monitor thread for this monitor.
     */
    private MonitorThread monitorThread;
  
    /**
     * The notification sequence number.
     */
    private long sequenceNumber;
    
    // Static --------------------------------------------------------
  
    // Constructors --------------------------------------------------
  
    /**
     * Construct a new monitor with the default values.
     */
    public Monitor()
    {
      monitorThread = new MonitorThread(this);
    }
  
    // Public --------------------------------------------------------
  
    // MonitorMBean implementation -----------------------------------
  
    public long getGranularityPeriod()
    {
      return granularityPeriod;
    }
  
    public String getObservedAttribute()
    {
      return observedAttribute;
    }
  
    public ObjectName getObservedObject()
    {
      return observedObject;
    }
  
    public boolean isActive()
    {
      return active;
    }
    public void setGranularityPeriod(long period)
      throws IllegalArgumentException
    {
      if (period <= 0)
        throw new IllegalArgumentException("Period must be positive.");
      granularityPeriod = period;
    }
  
    public void setObservedAttribute(String attribute)
    {
      observedAttribute = attribute;
      // REVIEW: not find grained enough?
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    public void setObservedObject(ObjectName object)
    {
      observedObject = object;
      // REVIEW: not find grained enough?
      alreadyNotified = RESET_FLAGS_ALREADY_NOTIFIED;
    }
  
    // REVIEW: Synchronized because of active/thread stop and enumeration
    public synchronized void start()
    {
      // Ignore if already active
      if (active)
        return;
      active = true;
  
      // Start the monitor thread
      monitorThread.start();
    }
  
    // REVIEW: Synchronized because of active/thread stop and enumeration
    public synchronized void stop()
    {
      // Ignore if not active
      if (!active)
        return;
  
      // Stop the monitor thread
      active = false;
      monitorThread.interrupt();
    }
  
    // MBeanRegistrationImplementation overrides ---------------------
  
    public ObjectName preRegister(MBeanServer server, ObjectName objectName)
      throws Exception
    {
      // Remember the server.
      this.server = server;
  
      // Use the passed object name.
      return objectName;
    }
  
    public void postRegister(Boolean registrationDone)
    {
    }
  
    public void preDeregister()
      throws Exception
    {
      // Stop the monitor before deregistration.
      stop();
    }
  
    public void postDeregister()
    {
    }
  
    // Package protected ---------------------------------------------
  
    /**
     * Run the monitor.<p>
     *
     * Retrieves the monitored attribute and passes it to each service.<p>
     *
     * Peforms the common error processing.
     * REVIEW: Use the internal interface?
     */
    void runMonitor()
    {
      // Monitor for uncaught errors
      try
      {
        MBeanInfo mbeanInfo = null;
        try
        {
          mbeanInfo = server.getMBeanInfo(observedObject);
        }
        catch (InstanceNotFoundException e)
        {
          sendObjectErrorNotification("The observed object is not registered.");
          return;
        }
  
        // Get the attribute information
        MBeanAttributeInfo[] mbeanAttributeInfo = mbeanInfo.getAttributes();
        MBeanAttributeInfo attributeInfo = null;
        for (int i = 0; i < mbeanAttributeInfo.length; i++)
        {
          if (mbeanAttributeInfo[i].getName().equals(observedAttribute))
          {
            attributeInfo = mbeanAttributeInfo[i];
            break;
          }
        }
  
        // The attribute must exist
        if (attributeInfo == null)
        {
          sendAttributeErrorNotification(
            "The observed attribute does not exist");
          return;
        }
        // The attribute must exist
        if (!attributeInfo.isReadable())
        {
          sendAttributeErrorNotification("Attribute not readable.");
          return;
        }
  
        // Determine the get method.
        String methodName = null;
        if (attributeInfo.isIs())
          methodName = "is" + observedAttribute;
        else
          methodName = "get" + observedAttribute;
  
        // Get the value
        Object value = null;
        try
        {
          value = server.invoke(observedObject, methodName,
                                new Object[0], new String[0]);
        }
        catch (InstanceNotFoundException e)
        {
          sendObjectErrorNotification("The observed object is not registered.");
          return;
        }
  
        // Check for null value
        if (value == null)
        {
          sendAttributeTypeErrorNotification("Attribute is null");
          return;
        }
  
        // Now pass the value to the respective monitor.
        monitor(attributeInfo, value);
      }
      // Notify an unexcepted error
      catch (Exception e)
      {
        sendRuntimeErrorNotification("General error: " + e.toString());
      }
    }
  
    /**
     * Perform the monitor specific processing. 
     *
     * @param attributeInfo the MBean attribute information.
     * @param value the value to monitor.
     */
    abstract void monitor(MBeanAttributeInfo attributeInfo, Object value)
      throws Exception;
  
    /**
     * Sends the notification
     *
     * @param type the notification type.
     * @param timestamp the time of the notification.
     * @param message the human readable message to send.
     * @param attribute the attribute name.
     * @param gauge the derived gauge.
     * @param trigger the trigger value.
     */
    void sendNotification(String type, long timestamp, String message, 
        String attribute, Object gauge, Object trigger)
    {
      long seq = 0;
      synchronized (this)
      {
        seq = ++sequenceNumber;
      }
      if (timestamp == 0)
        timestamp = System.currentTimeMillis();
      sendNotification(new MonitorNotification(type, this, seq,
                       timestamp, message, gauge,
                       attribute, observedObject, trigger));
    }
  
    /**
     * Send a runtime error notification.
     *
     * @param message the human readable message to send.
     */
    void sendRuntimeErrorNotification(String message)
    {
      if ((alreadyNotified & RUNTIME_ERROR_NOTIFIED) == 0)
        sendNotification(MonitorNotification.RUNTIME_ERROR, 0,
          message, null, null, null);
      alreadyNotified |= RUNTIME_ERROR_NOTIFIED;
    }
  
    /**
     * Send an object error notification.
     *
     * @param message the human readable message to send.
     */
    void sendObjectErrorNotification(String message)
    {
      if ((alreadyNotified & OBSERVED_OBJECT_ERROR_NOTIFIED) == 0)
        sendNotification(MonitorNotification.OBSERVED_OBJECT_ERROR, 0,
          message, null, null, null);
      alreadyNotified |= OBSERVED_OBJECT_ERROR_NOTIFIED;
    }
  
    /**
     * Send an attribute error notification.
     *
     * @param message the human readable message to send.
     */
    void sendAttributeErrorNotification(String message)
    {
      if ((alreadyNotified & OBSERVED_ATTRIBUTE_ERROR_NOTIFIED) == 0)
        sendNotification(MonitorNotification.OBSERVED_ATTRIBUTE_ERROR, 0,
          message, observedAttribute, null, null);
      alreadyNotified |= OBSERVED_ATTRIBUTE_ERROR_NOTIFIED;
    }
  
    /**
     * Send an attribute type error notification.
     *
     * @param message the human readable message to send.
     */
    void sendAttributeTypeErrorNotification(String message)
    {
      if ((alreadyNotified & OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED) == 0)
        sendNotification(MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, 0,
          message, observedAttribute, null, null);
      alreadyNotified |= OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED;
    }
  
    // Protected -----------------------------------------------------
  
    // Private -------------------------------------------------------
  
    // Inner classes -------------------------------------------------
  
    /**
     * A monitor thread.
     */
    private class MonitorThread
      extends Thread
    {
      // Attributes ----------------------------------------------------
  
      // The monitoring to perform
      private Monitor monitor;
  
      // Constructors --------------------------------------------------
  
      // Public --------------------------------------------------------
  
      /**
       * Create a monitor thread to periodically perform monitoring.
       *
       * @param monitor the montioring to perform.
       */
     public MonitorThread(Monitor monitor)
     {
       this.monitor = monitor;
     }
  
      // Thread overrides ----------------------------------------------
  
      /**
       * Wait until the monitor time or until we are interrupted by
       * stop. When active, run the monitor.
       */
      public void run()
      {
        // Keep going until we are stopped
        while (isActive())
        {
          // Perform the monitoring
          monitor.runMonitor();
  
          // Wait until the next monitor time
          doWait();
        }
      }
  
      /**
       * Wait until the next monitor.
       */
      private synchronized void doWait()
      {
        try
        {
            wait(getGranularityPeriod());
        }
        catch (InterruptedException ignored)
        {
        }
      }
    }
  }
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/MonitorMBean.java
  
  Index: MonitorMBean.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import javax.management.ObjectName;
  
  /**
   * The monitor service MBean interface. <p>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public interface MonitorMBean
  {
    // Constants -----------------------------------------------------
    
    // Static --------------------------------------------------------
    
    // Public --------------------------------------------------------
  
    /**
     * Retrieves the granularity period in milliseconds.<p>
     *
     * The monitoring takes place once per granularity period.
     *
     * @return the granularity period.
     */
    public long getGranularityPeriod();
  
    /**
     * Retrieves the name of the attribute monitored.
     *
     * @return the attribute monitored.
     */
    public String getObservedAttribute();
  
    /**
     * Retrieves the object name of the MBean monitored.
     *
     * @return the object name.
     */
    public ObjectName getObservedObject();
  
    /**
     * Tests whether this monitoring service is active.
     *
     * @return true when the service is active, false otherwise.
     */
    public boolean isActive();
  
    /**
     * Sets the granularity period in milliseconds.<p>
     *
     * The monitoring takes place once per granularity period.<p>
     *
     * The default value is 10 seconds.
     *
     * @param period the granularity period.
     * @exception IllegalArgumentException when the period is not positive.
     */
    public void setGranularityPeriod(long period)
      throws IllegalArgumentException;
  
    /**
     * Sets the name of the attribute monitored.<p>
     *
     * The default value is null.
     *
     * @param attribute the attribute monitored.
     * @exception IllegalArgumentException when the period is not positive.
     */
    public void setObservedAttribute(String attribute);
  
    /**
     * Sets the object name of the MBean monitored.<p>
     *
     * The default value is null.
     *
     * @param object the object name.
     */
    public void setObservedObject(ObjectName object);
  
    /**
     * Starts the monitor.
     */
    public void start();
  
    /**
     * Stops the monitor.
     */
    public void stop();
  }
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/MonitorNotification.java
  
  Index: MonitorNotification.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import java.io.Serializable;
  
  import javax.management.Notification;
  import javax.management.ObjectName;
  
  /**
   * A notification from one of the monitor services.<p>
   *
   * The notification occurs only when the state is first entered.<p>
   *
   * All monitor services produce the following notifications.
   * <ul>
   * <li> {@link #OBSERVED_OBJECT_ERROR} when the MBean is not registered.
   * </li>
   * <li> {@link #OBSERVED_ATTRIBUTE_ERROR} when the MBean's attribute does
   *      not exist.
   * </li>
   * <li> {@link #OBSERVED_ATTRIBUTE_TYPE_ERROR} when the MBean's attribute is
   *      not of the correct type for the monitor or the derived gauge value.
   * </li>
   * <li> {@link #RUNTIME_ERROR} for any other error.
   * </li>
   * </ul>
   * The counter monitor produces the following notifications.
   * <ul>
   * <li> {@link #THRESHOLD_ERROR} when one of the monitors threshold vaues is 
   * of an incorrect type.
   * </li>
   * <li> {@link #THRESHOLD_VALUE_EXCEEDED} when the counter exceeds the 
   * threshold.
   * </li>
   * </ul>
   * The gauge monitor produces the following notifications.
   * <ul>
   * <li> {@link #THRESHOLD_ERROR} when one of the monitors threshold vaues is 
   * of an incorrect type.
   * </li>
   * <li> {@link #THRESHOLD_HIGH_VALUE_EXCEEDED} when the attribute exceeds
   * the high threshold value.
   * </li>
   * <li> {@link #THRESHOLD_LOW_VALUE_EXCEEDED} when the attribute exceeds
   * the low threshold value.
   * </li>
   * </ul>
   * The string monitor produces the following notifications.
   * <ul>
   * <li> {@link #STRING_TO_COMPARE_VALUE_DIFFERED} when the attribute no longer
   * matches the specified value.
   * </li>
   * <li> {@link #STRING_TO_COMPARE_VALUE_DIFFERED} when the attribute matches 
   * the specified value.
   * </li>
   * </ul>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public class MonitorNotification
    extends Notification
    implements Serializable
  {
    // Constants -----------------------------------------------------
  
    /**
     * Notification type when an MBean doesn't contain the specified
     * attribute. The observed object name and observed attribute name
     * are sent in the notification.
     */
    public static final String OBSERVED_ATTRIBUTE_ERROR = 
                               "jmx.monitor.error.attribute";
  
    /**
     * Notification type when an attribute is null or the attribute has
     * an incorrect type for the monitor service. The observed object name 
     * and observed attribute name are sent in the notification.
     */
    public static final String OBSERVED_ATTRIBUTE_TYPE_ERROR = 
                               "jmx.monitor.error.type";
  
    /**
     * Notification type when an MBean is not registered. The observed object 
     * name is sent in the notification.
     */
    public static final String OBSERVED_OBJECT_ERROR = 
                               "jmx.monitor.error.mbean";
  
    /**
     * Notification type for any other error.
     */
    public static final String RUNTIME_ERROR = 
                               "jmx.monitor.error.runtime";
  
    /**
     * Notification type when an attribute no longer matches the specified
     * value of a StringMonitor. The observed object name, observed attribute
     * name, derived gauge (actual value) and trigger (monitor value) are
     * sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String STRING_TO_COMPARE_VALUE_DIFFERED = 
                               "jmx.monitor.string.differs";
  
    /**
     * Notification type when an attribute changes to match the specified
     * value of a StringMonitor. The observed object name, observed attribute
     * name, derived gauge (actual value) and trigger (monitor value) are
     * sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String STRING_TO_COMPARE_VALUE_MATCHED = 
                               "jmx.monitor.string.matches";
  
    /**
     * Notification type when an attribute's threshold parameters (threshold,
     * low threshold, high threshold, offset or modules) are not of the
     * correct type. The observed object name and observed attribute
     * are sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String THRESHOLD_ERROR = 
                               "jmx.monitor.error.threshold";
    /**
     * Notification type when a counter attribute changes to exceed the
     * specified threshold value. The observed object name, observed attribute
     * name, derived gauge (actual value) and trigger (threshold value) are
     * sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String THRESHOLD_VALUE_EXCEEDED = 
                               "jmx.monitor.counter.threshold";
  
    /**
     * Notification type when a guage attribute changes to exceed the
     * specified threshold high value. The observed object name, 
     * observed attribute name, derived gauge (actual value) and 
     * trigger (threshold value) are sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String THRESHOLD_HIGH_VALUE_EXCEEDED = 
                               "jmx.monitor.gauge.high";
  
    /**
     * Notification type when a gauge attribute changes to exceed the
     * specified threshold low value. The observed object name, 
     * observed attribute name, derived gauge (actual value) and 
     * trigger (threshold value) are sent in the notification.
     * REVIEW: Verify this.
     */
    public static final String THRESHOLD_LOW_VALUE_EXCEEDED = 
                               "jmx.monitor.gauge.low";
    
    // Attributes ----------------------------------------------------
    
    /**
     * The derived gauge.
     */
    private Object derivedGauge;
    
    /**
     * The observed attribute.
     */
    private String observedAttribute;
    
    /**
     * The observed object.
     */
    private ObjectName observedObject;
    
    /**
     * The trigger of the notification.
     */
    private Object trigger;
  
    // Static --------------------------------------------------------
    
    // Constructors --------------------------------------------------
  
    /**
     * Construct a new monitor notification.
     *
     * @param type the notification type.
     * @param source the notification source.
     * @param sequenceNumber the notification sequence within the source object.
     * @param timeStamp the time the notification was sent.
     * @param message the detailed message.
     * @param derivedGauge the actual value.
     * @param observedAttribute the monitored attribute.
     * @param observedObject the monitored MBean.
     * @param trigger the value monitor value.
     */
    MonitorNotification(String type, Object source, long sequenceNumber, 
                 long timeStamp, String message, Object derivedGauge, 
                 String observedAttribute, ObjectName observedObject,
                 Object trigger)
    {
      super(type, source, sequenceNumber, timeStamp, message);
      this.derivedGauge = derivedGauge;
      this.observedAttribute = observedAttribute;
      this.observedObject = observedObject;
      this.trigger = trigger;
    }
  
    // Public --------------------------------------------------------
  
    /**
     * Retrieves the derived gauge. See each monitor service for
     * the definition of this value.
     *
     * @return the derived gauge.
     */
    public Object getDerivedGauge()
    {
      return derivedGauge;
    }
  
    /**
     * Retrieves the name of the attribute monitored.
     *
     * @return the name of the monitored attribute.
     */
    public String getObservedAttribute()
    {
      return observedAttribute;
    }
  
    /**
     * Retrieves the name of the MBean monitored.
     *
     * @return the registered object name.
     */
    public ObjectName getObservedObject()
    {
      return observedObject;
    }
  
    /**
     * Retrieves the trigger value of the notification. See each monitor
     * service for the values that trigger notifications.
     *
     * @return the trigger.
     */
    public Object getTrigger()
    {
      return trigger;
    }
  
    // X implementation ----------------------------------------------
  
    // Notification overrides ----------------------------------------
  
    // Package protected ---------------------------------------------
  
    // Protected -----------------------------------------------------
  
    // Private -------------------------------------------------------
  
    // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  
jmx/src/main/javax/management/monitor/MonitorSettingException.java
  
  Index: MonitorSettingException.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package javax.management.monitor;
  
  import javax.management.JMRuntimeException;
  
  /**
   * Thrown by a monitor when a monitor setting becomes invalid.<p>
   *
   * ISSUE: Where and how is this used, if at all?
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   */
  public class MonitorSettingException
     extends JMRuntimeException
  {
     // Attributes ----------------------------------------------------
  
     // Static --------------------------------------------------------
  
     // Constructors --------------------------------------------------
  
     /**
      * Construct a new MonitorSettingException with no message.
      */
     public MonitorSettingException()
     {
        super();
     }
  
     /**
      * Construct a new MonitorSettingException with the given message.
      *
      * @param message the error message.
      */
     public MonitorSettingException(String message)
     {
        super(message);
     }
  }
  
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/StringMonitor.java
  
  Index: StringMonitor.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  import javax.management.MBeanAttributeInfo;
  import javax.management.MBeanNotificationInfo;
  
  // REVIEW: Check synchronization
  
  /**
   * The string monitor service.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public class StringMonitor
    extends Monitor
    implements StringMonitorMBean
  {
    // Constants -----------------------------------------------------
  
    /**
     * The string match has been notified.
     */
    int STRING_MATCHES_NOTIFIED = 16;
  
    /**
     * The string differs has been notified.
     */
    int STRING_DIFFERS_NOTIFIED = 32;
  
    // Attributes ----------------------------------------------------
  
    /**
     * The derived gauge.
     */
    private String derivedGauge = new String();
  
    /**
     * The derived gauge timeStamp.
     */
    private long derivedGaugeTimeStamp = 0;
  
    /**
     * The comparison string.
     */
    String stringToCompare = new String();
  
    /**
     * Notify Matches.
     */
    boolean notifyMatch = false;
  
    /**
     * Notify Differs.
     */
    boolean notifyDiffer = false;
  
    // Static --------------------------------------------------------
  
    // Constructors --------------------------------------------------
  
    /**
     * Default Constructor
     */
    public StringMonitor()
    {
      dbgTag = "StringMonitor";
    }
  
    // Public --------------------------------------------------------
  
    public MBeanNotificationInfo[] getNotificationInfo()
    {
      MBeanNotificationInfo[] result = new MBeanNotificationInfo[1];
      String[] types = new String[]
      {
        MonitorNotification.RUNTIME_ERROR,
        MonitorNotification.OBSERVED_OBJECT_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_ERROR,
        MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
        MonitorNotification.STRING_TO_COMPARE_VALUE_MATCHED,
        MonitorNotification.STRING_TO_COMPARE_VALUE_DIFFERED
      };
      result[0] = new MBeanNotificationInfo(types,
        "javax.management.monitor.MonitorNotification",
        "Notifications sent by the String Monitor Service MBean");
      return result;
    }
  
    // StringMonitorMBean implementation -----------------------------
  
    public String getDerivedGauge()
    {
      return derivedGauge;
    }
  
    public long getDerivedGaugeTimeStamp()
    {
      return derivedGaugeTimeStamp;
    }
  
    public String getStringToCompare()
    {
      return stringToCompare;
    }
  
    public void setStringToCompare(String value)
      throws IllegalArgumentException
    {
      if (value == null)
        throw new IllegalArgumentException("Null string to compare.");
      this.stringToCompare = value;
    }
  
    public boolean getNotifyMatch()
    {
      return notifyMatch;
    }
  
    public void setNotifyMatch(boolean value)
    {
      notifyMatch = value;
    }
  
    public boolean getNotifyDiffer()
    {
      return notifyDiffer;
    }
  
    public void setNotifyDiffer(boolean value)
    {
      notifyDiffer = value;
    }
  
    // Override start to set initial gauge.
    public synchronized void start()
    {
      derivedGauge = new String();
      derivedGaugeTimeStamp = System.currentTimeMillis();
      super.start();
    }
    // Package protected ---------------------------------------------
  
    void monitor(MBeanAttributeInfo attributeInfo, Object value)
      throws Exception
    {
      // Must be a string.
      if (!(value instanceof String))
      {
        sendAttributeTypeErrorNotification("Not a string attribute");
        return;
      }
  
      // Get the gauge and record when we got it.
      derivedGauge = (String) value;
      derivedGaugeTimeStamp = System.currentTimeMillis();
  
      // Try to fire the relevant event.
      if (value.equals(stringToCompare))
        sendStringMatchesNotification((String) value);
      else
        sendStringDiffersNotification((String) value);
    }
  
    /**
     * Send an string matches notification.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendStringMatchesNotification(String value)
    {
      if (notifyMatch && ((alreadyNotified & STRING_MATCHES_NOTIFIED) == 0))
      {
        sendNotification(MonitorNotification.STRING_TO_COMPARE_VALUE_MATCHED,
          derivedGaugeTimeStamp, "matches", observedAttribute, value, 
          stringToCompare);
        alreadyNotified |= STRING_MATCHES_NOTIFIED;
      }
      alreadyNotified &= ~STRING_DIFFERS_NOTIFIED;
    }
  
    /**
     * Send an string differs notification.<p>
     *
     * This is only performed when requested and it has not already been sent.
     *
     * @param value the attribute value.
     */
    void sendStringDiffersNotification(String value)
    {
      if (notifyDiffer && ((alreadyNotified & STRING_DIFFERS_NOTIFIED) == 0))
      {
        sendNotification(MonitorNotification.STRING_TO_COMPARE_VALUE_DIFFERED,
          derivedGaugeTimeStamp, "differs", observedAttribute, value, 
          stringToCompare);
        alreadyNotified |= STRING_DIFFERS_NOTIFIED;
      }
      alreadyNotified &= ~STRING_MATCHES_NOTIFIED;
    }
  
    // Protected -----------------------------------------------------
  
    // Private -------------------------------------------------------
  
    // Inner classes -------------------------------------------------
  }
  
  
  
  1.1                  jmx/src/main/javax/management/monitor/StringMonitorMBean.java
  
  Index: StringMonitorMBean.java
  ===================================================================
  /*
  * JBoss, the OpenSource EJB server
  *
  * Distributable under LGPL license.
  * See terms of license at gnu.org.
  */
  package javax.management.monitor;
  
  /**
   * The string monitor service MBean interface. <p>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Adrian Brock</a>
   * @version $Revision: 1.1 $
   *
   */
  public interface StringMonitorMBean
    extends MonitorMBean
  {
    // Constants -----------------------------------------------------
    
    // Static --------------------------------------------------------
    
    // Public --------------------------------------------------------
  
    /**
     * Retrieves the derived gauge.
     *
     * @return the derived gauge.
     */
    public String getDerivedGauge();
  
    /**
     * Retrieves the derived gauge timestamp.
     *
     * @return the derived gauge timestamp.
     */
    public long getDerivedGaugeTimeStamp();
  
    /**
     * Retrieves the string to compare with the observed attribute.
     *
     * @return the comparison string.
     */
    public String getStringToCompare();
  
    /**
     * Sets the string to compare with the observed attribute.
     *
     * @param value the comparison string.
     * @exception IllegalArgumentException when specified string is null.
     */
    public void setStringToCompare(String value)
      throws IllegalArgumentException;
  
    /**
     * Retrieves the matching on/off switch.
     *
     * @return true if the notification occurs when the string matches, false
     *         otherwise.
     */
    public boolean getNotifyMatch();
  
    /**
     * Sets the matching on/off switch.
     *
     * @param value pass true for a notification when the string matches, false
     *        otherwise.
     */
    public void setNotifyMatch(boolean value);
  
    /**
     * Retrieves the differs on/off switch.
     *
     * @return true if the notification occurs when the string differs, false
     *         otherwise.
     */
    public boolean getNotifyDiffer();
  
    /**
     * Sets the differs on/off switch.
     *
     * @param value pass true for a notification when the string differs, false
     *        otherwise.
     */
    public void setNotifyDiffer(boolean value);
  }
  
  
  1.1                  jmx/src/main/javax/management/monitor/package.html
  
  Index: package.html
  ===================================================================
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  <html>
    <head>
      <!--
  
      JBoss, the OpenSource J2EE webOS
  
      This library is free software; you can redistribute it and/or modify it   
      under the terms of the GNU Lesser General Public License as published     
      by the Free Software Foundation; either version 2 of the License, or      
      (at your option) any later version.                                       
                                                                                
      This library is distributed in the hope that it will be useful, but       
      WITHOUT ANY WARRANTY; without even the implied warranty of                
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         
      Lesser General Public License for more details.                           
  
      -->
      <!-- $Id: package.html,v 1.1 2001/12/21 01:39:37 ejort Exp $ -->
    </head>
  
    <body bgcolor="white">
      <p><em>The JBossMX monitor services</em>.
  
      <h2>Package Specification</h2>
      <ul>
        <li>The monitor services allow notifications to be sent when
            attribute values change. The notification is NOT done in
            real time, rather the value is polled at regular intervals.
            Notifications are also sent when the monitoring cannot be
            performed for various reasons.
        </li>
        <li>The monitor services are registered as separate MBeans for
            each attribute. Any number of notification listeners can be
            added to these services, to perform the required operations.
        </li>
        <li>The <i>CounterMonitor</i> is used for "integer" attributes that 
            only increase, except for modulus behaviour (e.g. a 24 hour clock).
        </li>
        <li>The <i>GaugeMonitor</i> is used for numeric attributes that can
            both increase and decrease.
        </li>
        <li>The <i>StringMonitor</i> is used for any attribute to check for
            a matching or differing value.
        </li>
      </ul>
        
      <h2>Related Documentation</h2>
      <ul>
        <li>TODO: get the link for the JMX specification.
      </ul>
  
      <h2>Package Status</h2>
      <ul>
        <li><font color="red"><b>ALPHA</b></font>
      </ul>
  
      <!-- Put @see and @since tags down here. -->
  
    </body>
  </html>
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to