This adds methods to emit notifications to our memory
bean implementation.

Changelog:

2006-07-22  Andrew John Hughes  <[EMAIL PROTECTED]>

        * gnu/java/lang/management/MemoryMXBeanImpl.java:
        (fireNotification(String,String,long,long,long,long,long)):
        Implemented.
        (fireThresholdExceededNotification(String,long,long,long,
        long,long)): Likewise.
        (fireCollectionThresholdExceededNotification(String,long,
        long,long,long,long)): Likewise.
        * java/lang/management/MemoryNotificationInfo.java:
        Use composite type from MemoryMXBeanImpl.
        * javax/management/openmbean/CompositeData.java:
        Correct documentation.
        * javax/management/openmbean/CompositeDataSupport.java,
        * javax/management/openmbean/InvalidKeyException.java:
        New files.

-- 
Andrew :-)

Escape the Java Trap with GNU Classpath!
http://www.gnu.org/philosophy/java-trap.html
public class gcj extends Freedom implements Java { ... }
Index: gnu/java/lang/management/MemoryMXBeanImpl.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/gnu/java/lang/management/MemoryMXBeanImpl.java,v
retrieving revision 1.2
diff -u -3 -p -u -r1.2 MemoryMXBeanImpl.java
--- gnu/java/lang/management/MemoryMXBeanImpl.java      18 Jul 2006 20:45:13 
-0000      1.2
+++ gnu/java/lang/management/MemoryMXBeanImpl.java      22 Jul 2006 10:55:27 
-0000
@@ -52,6 +52,13 @@ import javax.management.NotificationEmit
 import javax.management.NotificationFilter;
 import javax.management.NotificationListener;
 
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+
 /**
  * Provides access to information about the memory 
  * management of the current invocation of the virtual
@@ -68,9 +75,56 @@ public final class MemoryMXBeanImpl
 
   private List listeners;
 
+  private long notificationCount;
+
+  public static CompositeType notifType;
+
+  public static CompositeType usageType;
+
+  static
+  {
+    try
+      {
+       CompositeType usageType = 
+         new CompositeType(MemoryUsage.class.getName(),
+                           "Describes the usage levels of a pool",
+                           new String[] { "init", "used",
+                                          "committed", "max"
+                           },
+                           new String[] { "Initial level",
+                                          "Used level",
+                                          "Committed level",
+                                          "Maximum level"
+                           },
+                           new OpenType[] {
+                             SimpleType.LONG, SimpleType.LONG,
+                             SimpleType.LONG, SimpleType.LONG
+                           });
+       CompositeType notifType =
+         new CompositeType(MemoryNotificationInfo.class.getName(),
+                           "Provides the notification info on memory usage",
+                           new String[] { "poolName", "usage", "count" },
+                           new String[] { "Name of the memory pool",
+                                          "Usage level of the memory pool",
+                                          "Number of times the threshold " +
+                                          "has been crossed"
+                           },
+                           new OpenType[] {
+                             SimpleType.STRING, usageType, SimpleType.LONG 
+                           });
+         }
+       catch (OpenDataException e)
+         {
+           throw new IllegalStateException("Something went wrong in creating " 
+
+                                           "the composite data types.", e);
+         }
+  }
+
+
   public MemoryMXBeanImpl()
   {
     listeners = new ArrayList();
+    notificationCount = 0;
   }
 
   public void gc()
@@ -203,4 +257,56 @@ public final class MemoryMXBeanImpl
       }
   }
 
+  public void fireNotification(String type, String poolName, long init, long 
used,
+                              long committed, long max, long count)
+  {
+    Notification notif = new Notification(type, this, notificationCount);
+    MemoryUsage usage = new MemoryUsage(init, used, committed, max);
+    CompositeData data;
+    try
+      {
+       data = new CompositeDataSupport(notifType, 
+                                       new String[] {
+                                         "poolName", "usage", "count"
+                                       },
+                                       new Object[] {
+                                         poolName, usage, Long.valueOf(count)
+                                       });
+      }
+    catch (OpenDataException e)
+      {
+       throw new IllegalStateException("Something went wrong in creating " +
+                                       "the composite data instance.", e);
+      }
+    notif.setUserData(data);
+    Iterator it = listeners.iterator();
+    while (it.hasNext())
+      {
+       ListenerData ldata = (ListenerData) it.next();
+       NotificationFilter filter = ldata.getFilter();
+       if (filter == null || filter.isNotificationEnabled(notif))
+         ldata.getListener().handleNotification(notif, ldata.getPassback());
+      }
+    ++notificationCount;
+  }
+
+  public void fireThresholdExceededNotification(String poolName, long init,
+                                               long used, long committed,
+                                               long max, long count)
+  {
+    fireNotification(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
+                    poolName, init, used, committed, max, count);
+  }
+
+  public void fireCollectionThresholdExceededNotification(String poolName,
+                                                         long init,
+                                                         long used,
+                                                         long committed,
+                                                         long max,
+                                                         long count)
+  {
+    
fireNotification(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED,
+                    poolName, init, used, committed, max, count);
+  }
+
 }
Index: java/lang/management/MemoryNotificationInfo.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/java/lang/management/MemoryNotificationInfo.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 MemoryNotificationInfo.java
--- java/lang/management/MemoryNotificationInfo.java    16 Jul 2006 19:22:07 
-0000      1.1
+++ java/lang/management/MemoryNotificationInfo.java    22 Jul 2006 10:55:27 
-0000
@@ -37,10 +37,10 @@ exception statement from your version. *
 
 package java.lang.management;
 
+import gnu.java.lang.management.MemoryMXBeanImpl;
+
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.OpenType;
 import javax.management.openmbean.SimpleType;
 
 /**
@@ -168,31 +168,7 @@ public class MemoryNotificationInfo
       return null;
     CompositeType type = data.getCompositeType();
     ThreadInfo.checkAttribute(type, "poolName", SimpleType.STRING);
-    try
-      {
-       CompositeType uType = 
-         new CompositeType(MemoryUsage.class.getName(),
-                           "Describes the usage levels of a pool",
-                           new String[] { "init", "used",
-                                          "committed", "max"
-                           },
-                           new String[] { "Initial level",
-                                          "Used level",
-                                          "Committed level",
-                                          "Maximum level"
-                           },
-                           new OpenType[] {
-                             SimpleType.LONG, SimpleType.LONG,
-                             SimpleType.LONG, SimpleType.LONG
-                           });
-       ThreadInfo.checkAttribute(type, "usage", uType);
-      }
-    catch (OpenDataException e)
-      {
-       throw new IllegalStateException("Something went wrong in creating " +
-                                       "the composite data type for the " +
-                                       "memory usage element.", e);
-      }
+    ThreadInfo.checkAttribute(type, "usage", MemoryMXBeanImpl.usageType);
     ThreadInfo.checkAttribute(type, "count", SimpleType.LONG);
     MemoryUsage usage = MemoryUsage.from((CompositeData) data.get("usage"));
     return new MemoryNotificationInfo(((String) data.get("poolName")),
Index: javax/management/openmbean/CompositeData.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/javax/management/openmbean/CompositeData.java,v
retrieving revision 1.1
diff -u -3 -p -u -r1.1 CompositeData.java
--- javax/management/openmbean/CompositeData.java       9 Jul 2006 13:56:22 
-0000       1.1
+++ javax/management/openmbean/CompositeData.java       22 Jul 2006 10:55:27 
-0000
@@ -73,9 +73,9 @@ public interface CompositeData
   /**
    * Compares the specified object with this object for equality.
    * The object is judged equivalent if it is non-null, and also
-   * an instance of [EMAIL PROTECTED] CompositeData} with the same values
-   * and types.  The two compared instances may be equivalent even
-   * if they represent different implementations of
+   * an instance of [EMAIL PROTECTED] CompositeData} with the same name-value
+   * mappings and types.  The two compared instances may be
+   * equivalent even if they represent different implementations of
    * [EMAIL PROTECTED] CompositeData}.
    *
    * @param obj the object to compare for equality.
@@ -105,7 +105,7 @@ public interface CompositeData
    *                                  empty string.
    * @throws InvalidKeyException if one of the keys does not exist.
    */
-  Object[] getAll(String[] key);
+  Object[] getAll(String[] keys);
 
   /**
    * Returns the composite type which corresponds to this instance
Index: javax/management/openmbean/CompositeDataSupport.java
===================================================================
RCS file: javax/management/openmbean/CompositeDataSupport.java
diff -N javax/management/openmbean/CompositeDataSupport.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/management/openmbean/CompositeDataSupport.java        22 Jul 2006 
10:55:27 -0000
@@ -0,0 +1,349 @@
+/* CompositeData.java -- A composite data structure implementation.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.management.openmbean;
+
+import java.io.Serializable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Provides an implementation of the [EMAIL PROTECTED] CompositeData}
+ * interface.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+public class CompositeDataSupport
+  implements CompositeData, Serializable
+{
+
+  /**
+   * Compatible with JDK 1.5
+   */
+  private static final long serialVersionUID = 8003518976613702244L;
+
+  /**
+   * Mapping of field names to values.
+   *
+   * @serial the map of field names to values.
+   */
+  private SortedMap contents;
+
+  /**
+   * The composite type which represents this composite data instance.
+   *
+   * @serial the type information for this instance.
+   */
+  private CompositeType compositeType;
+
+  /**
+   * Constructs a new [EMAIL PROTECTED] CompositeDataSupport} instance with the
+   * specified type using field names and values from the supplied map.
+   * The keys of the map become the field names, while the values
+   * become the values of each respective field.  This constructor simply
+   * calls the other constructor, with the two arrays formed using the
+   * keys and values of this map, respectively.  Thus, the input parameters
+   * given should conform to the same requirements given there (i.e. no
+   * null values or empty strings).
+   *
+   * @param type the composite type of this composite data structure.
+   * @param items a mapping of field names to values.  This should match
+   *              the mappings given by the type (i.e. for each mapping
+   *              in the type, there should be a corresponding field name
+   *              with a value of the correct type).
+   * @throws IllegalArgumentException if the type, the map or any of the keys
+   *                                  or values in the map are 
<code>null</code>,
+   *                                  or if any key from the map is an empty
+   *                                  string.
+   * @throws OpenDataException if a mismatch occurs between the map and the
+   *                           field name/type specification given by the
+   *                           [EMAIL PROTECTED] CompositeType} instance.  
This may be
+   *                           due to the two having a different size, a
+   *                           mismatch between keys or an incorrectly typed
+   *                           value.
+   * @throws ArrayStoreException if one of the keys is not a
+   *                             [EMAIL PROTECTED] java.lang.String} (thus 
calling a failure
+   *                             in converting the keys to an array of 
strings).
+   */
+  public CompositeDataSupport(CompositeType type, Map items)
+    throws OpenDataException
+  {
+    this(type, 
+        (String[]) items.keySet().toArray(new String[items.size()]),
+        items.values().toArray());
+  }
+
+  /**
+   * Constructs a new [EMAIL PROTECTED] CompositeDataSupport} instance with the
+   * specified type using the supplied arrays of field names and
+   * values.  Neither the type, the two arrays or any elements of the
+   * arrays may be <code>null</code>.  The [EMAIL PROTECTED] java.lang.String}s
+   * within the <code>names</code> array must be non-empty.  The
+   * arrays must match in size and order, as each element of the
+   * <code>names</code> array is matched against the corresponding
+   * value in the <code>values</code> array.  Internally, the two are
+   * stored in a map, lexographically ordered using the field names.
+   * The data given should also conform to the description of the
+   * instance given by the [EMAIL PROTECTED] CompositeType} instance supplied.
+   *
+   * @param type the composite type of this composite data structure.
+   * @param names the field names.
+   * @param values the corresponding values of the fields.
+   * @throws IllegalArgumentException if the type, the arrays or any of the 
keys
+   *                                  or values in the arrays are 
<code>null</code>,
+   *                                  or if any key from <code>names</code> is
+   *                                  an empty string.  This also occurs if the
+   *                                  arrays differ in length.
+   * @throws OpenDataException if a mismatch occurs between the arrays and the
+   *                           field name/type specification given by the
+   *                           [EMAIL PROTECTED] CompositeType} instance.  
This may be
+   *                           due to a differing number of field names, a
+   *                           mismatch between names or an incorrectly typed
+   *                           value.
+   */
+  public CompositeDataSupport(CompositeType type, String[] names, Object[] 
values)
+    throws OpenDataException
+  {
+    if (type == null)
+      throw new IllegalArgumentException("The given composite type is null.");
+    compositeType = type;
+    if (names == null)
+      throw new IllegalArgumentException("The names array is null.");
+    if (values == null)
+      throw new IllegalArgumentException("The values array is null.");
+    if (names.length != values.length)
+      throw new IllegalArgumentException("The sizes of the arrays differ.");
+    Set typeKeys = type.keySet();
+    if (typeKeys.size() != names.length)
+      throw new OpenDataException("The number of field names does not match " +
+                                 "the type description.");
+    contents = new TreeMap();
+    for (int a = 0; a < names.length; ++a)
+      {
+       if (names[a] == null)
+         throw new IllegalArgumentException("Element " + a + " of the names " +
+                                            "array is null.");
+       if (names[a].length() == 0)
+         throw new IllegalArgumentException("Element " + a + " of the names " +
+                                            "array is an empty string.");
+       if (values[a] == null)
+         throw new IllegalArgumentException("Element " + a + " of the values " 
+
+                                            "array is null.");
+       if (!(typeKeys.contains(names[a])))
+         throw new OpenDataException("The name, " + names[a] + ", is not a " +
+                                     "field in the given type description.");
+       if (!(type.getType(names[a]).isValue(values[a])))
+         throw new OpenDataException("The value, " + values[a] + ", is not a " 
+
+                                     "valid value for the " + names[a] + " 
field.");
+       contents.put(names[a], values[a]);
+      }
+  }
+
+  /**
+   * Returns true if this [EMAIL PROTECTED] CompositeData} instance contains
+   * the specified key.  This method always returns false for
+   * an input key equal to <code>null</code> or the empty string.
+   *
+   * @param key the key to find in the structure.
+   * @return true if the key exists.
+   */
+  public boolean containsKey(String key)
+  {
+    if (key == null || key.length() == 0)
+      return false;
+    else
+      return contents.containsKey(key);
+  }
+
+  /**
+   * Returns true if this [EMAIL PROTECTED] CompositeData} instance has
+   * a value equal to that supplied.
+   *
+   * @param value the value to look for.
+   * @return true if the value exists.
+   */
+  public boolean containsValue(Object value)
+  {
+    return contents.containsValue(value);
+  }
+
+
+  /**
+   * Compares the specified object with this object for equality.
+   * The object is judged equivalent if it is non-null, and also
+   * an instance of [EMAIL PROTECTED] CompositeData} with the same name-value
+   * mappings and types.  The two compared instances may be
+   * equivalent even if they represent different implementations of
+   * [EMAIL PROTECTED] CompositeData}.
+   *
+   * @param obj the object to compare for equality.
+   * @return true if <code>obj</code> is equal to <code>this</code>.
+   */
+  public boolean equals(Object obj)
+  {
+    if (!(obj instanceof CompositeData))
+      return false;
+    CompositeData data = (CompositeData) obj;
+    if (!(data.getCompositeType().equals(compositeType)))
+      return false;
+    Iterator it = contents.keySet().iterator();
+    while (it.hasNext())
+      {
+       String key = (String) it.next();
+       if (!(data.containsKey(key)))
+         return false;
+       if (!(data.get(key).equals(contents.get(key))))
+         return false;
+      }
+    return true;
+  }
+
+  /**
+   * Retrieves the value for the specified key.
+   *
+   * @param key the key whose value should be returned.
+   * @return the matching value.
+   * @throws IllegalArgumentException if the key is <code>null</code>
+   *                                  or the empty string.
+   * @throws InvalidKeyException if the key does not exist.
+   */
+  public Object get(String key)
+  {
+    if (key == null)
+      throw new IllegalArgumentException("The supplied key is null.");
+    if (key.length() == 0)
+      throw new IllegalArgumentException("The supplied key is the empty 
string.");
+    if (!(contents.containsKey(key)))
+      throw new InvalidKeyException("The supplied key does not exist.");
+    return contents.get(key);
+  }
+
+  /**
+   * Returns the appropriate value for each key in the given array,
+   * using the same ordering.
+   *
+   * @param keys the keys whose values should be returned.
+   * @return the matching values.
+   * @throws IllegalArgumentException if one of the keys is
+   *                                  <code>null</code> or the
+   *                                  empty string.
+   * @throws InvalidKeyException if one of the keys does not exist.
+   */
+  public Object[] getAll(String[] keys)
+  {
+    Object[] values = new Object[keys.length];
+    for (int a = 0; a < keys.length; ++a)
+      values[a] = get(keys[a]);
+    return values;
+  }
+
+
+  /**
+   * Returns the composite type which corresponds to this instance
+   * of [EMAIL PROTECTED] CompositeData}.
+   *
+   * @return the composite type for this instance.
+   */
+  public CompositeType getCompositeType()
+  {
+    return compositeType;
+  }
+
+  /**
+   * Returns the hash code of this instance.  The hash code is
+   * computed as the sum of the hash codes of all the values plus
+   * the hash code of the composite type.  As equality comparisons
+   * take place using this same information, this should ensure that
+   * the property, <code>e1.equals(e2)</code> implies
+   * <code>e1.hashCode() == e2.hashCode(), holds for any pair
+   * of instances, <code>e1</code> and <code>e2</code>. However,
+   * this relies on the other instance implementing the
+   * <code>hashCode</code> method correctly, if it is not an
+   * instance of [EMAIL PROTECTED] CompositeDataSupport}.
+   *
+   * @return the hash code of this [EMAIL PROTECTED] CompositeData}.
+   * @see Object#equals(Object)
+   */
+  public int hashCode()
+  {
+    int code = compositeType.hashCode();
+    Iterator it = values().iterator();
+    while (it.hasNext())
+      code += it.next().hashCode();
+    return code;
+  }
+
+
+  /**
+   * Returns a textual representation of this instance.  The
+   * exact format is left up to the implementation, but it
+   * should contain the name of the implementing class,
+   * the name of the type and a mapping of the form
+   * <code>key=value</code> for each pair of key and value.
+   *
+   * @return a [EMAIL PROTECTED] java.lang.String} representation of the
+   *         object.
+   */
+  public String toString()
+  {
+    return getClass().getName() +
+      "[compositeType=" + compositeType +
+      ",contents=" + contents +
+      "]";
+  }
+
+  /**
+   * Returns a read-only collection of the values associated with
+   * this instance.  The values are sorted using the lexicographic
+   * ordering of the corresponding keys.
+   *
+   * @return the values of this instance.
+   */
+  public Collection values()
+  {
+    return Collections.unmodifiableCollection(contents.values());
+  }
+
+}
+
Index: javax/management/openmbean/InvalidKeyException.java
===================================================================
RCS file: javax/management/openmbean/InvalidKeyException.java
diff -N javax/management/openmbean/InvalidKeyException.java
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ javax/management/openmbean/InvalidKeyException.java 22 Jul 2006 10:55:27 
-0000
@@ -0,0 +1,77 @@
+/* InvalidKeyException.java -- Thrown by an invalid composite/tabular key.
+   Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package javax.management.openmbean;
+
+/**
+ * Thrown when an invalid key (a field name or row index) is
+ * passed to a method of the [EMAIL PROTECTED] CompositeData} or
+ * [EMAIL PROTECTED] TabularData} classes.
+ *
+ * @author Andrew John Hughes ([EMAIL PROTECTED])
+ * @since 1.5
+ */
+public class InvalidKeyException
+  extends IllegalArgumentException
+{
+
+  /**
+   * Compatible with JDK 1.5
+   */
+  private static final long serialVersionUID = 4224269443946322062L;
+
+  /**
+   * Constructs a new <code>InvalidKeyException</code>.
+   */
+  public InvalidKeyException()
+  {
+    super();
+  }
+
+  /**
+   * Constructs a new <code>InvalidKeyException</code>
+   * with the specified message.
+   *
+   * @param message the error message to give to the user.
+   */
+  public InvalidKeyException(String message)
+  {
+    super(message);
+  }
+
+}
+

Attachment: signature.asc
Description: Digital signature

Reply via email to