You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by nd...@apache.org on 2007/01/13 06:08:52 UTC
svn commit: r495839 [2/7] - in
/harmony/enhanced/classlib/trunk/modules/lang-management: ./ META-INF/
make/ src/main/java/com/ src/main/java/com/ibm/ src/main/java/com/ibm/lang/
src/main/java/com/ibm/lang/management/ src/main/java/java/lang/management/...
Added: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/ManagementUtils.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/ManagementUtils.java?view=auto&rev=495839
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/ManagementUtils.java (added)
+++ harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/ManagementUtils.java Fri Jan 12 21:08:48 2007
@@ -0,0 +1,1535 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.lang.management;
+
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.CompilationMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryNotificationInfo;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.lang.management.MemoryUsage;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.LoggingMXBean;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.openmbean.ArrayType;
+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;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+/**
+ * Support methods for com.ibm.lang.management classes.
+ *
+ */
+public class ManagementUtils {
+
+ private static Map<String, MBeanInfo> infoMap = buildInfoMap();
+
+ private static CompositeType MEMORYUSAGE_COMPOSITETYPE;
+
+ private static CompositeType MEMORYNOTIFICATIONINFO_COMPOSITETYPE;
+
+ private static CompositeType THREADINFO_COMPOSITETYPE;
+
+ private static CompositeType STACKTRACEELEMENT_COMPOSITETYPE;
+
+ /**
+ * System property setting used to decide if non-fatal exceptions should be
+ * written out to console.
+ */
+ public static final boolean VERBOSE_MODE = checkVerboseProperty();
+
+ /**
+ * @return the singleton <code>ClassLoadingMXBean</code> instance.
+ */
+ public static ClassLoadingMXBeanImpl getClassLoadingBean() {
+ return ClassLoadingMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return boolean indication of whether or not the system property
+ * <code>com.ibm.lang.management.verbose</code> has been set.
+ */
+ private static boolean checkVerboseProperty() {
+ return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ return System.getProperty("com.ibm.lang.management.verbose") != null;
+ }// end method run
+ });
+ }
+
+ /**
+ * Convenenience method to return the {@link MBeanInfo} object that
+ * corresponds to the specified <code>MXBean</code> type.
+ *
+ * @param name
+ * the fully qualified name of an <code>MXBean</code>
+ * @return if <code>name</code> has the value of a known
+ * <code>MXBean</code> type then returns the
+ * <code>MBeanInfo</code> meta data for that type. If
+ * <code>name</code> is not the name of a known
+ * <code>MXBean</code> kind then returns <code>null</code>.
+ */
+ static MBeanInfo getMBeanInfo(String name) {
+ return infoMap.get(name);
+ }
+
+ /**
+ * Builds a <code>Map</code> of all the {@link MBeanInfo} instances for
+ * each of the platform beans. The map is keyed off the name of each bean
+ * type.
+ *
+ * @return a <code>Map</code> of all the platform beans'
+ * <code>MBeanInfo</code> instances.
+ */
+ private static Map<String, MBeanInfo> buildInfoMap() {
+ HashMap<String, MBeanInfo> map = new HashMap<String, MBeanInfo>();
+ addClassLoadingInfo(map);
+ addCompilationBeanInfo(map);
+ addLoggingBeanInfo(map);
+ addMemoryManagerBeanInfo(map);
+ addGarbageCollectorBeanInfo(map);
+ addMemoryBeanInfo(map);
+ addMemoryPoolBeanInfo(map);
+ addOperatingSystemBeanInfo(map);
+ addRuntimeBeanInfo(map);
+ addThreadBeanInfo(map);
+ return map;
+ }
+
+ /**
+ * Creates the metadata for the {@link java.lang.management.ThreadMXBean}.
+ * For this type of platform bean the metadata covers :
+ * <ul>
+ * <li>12 attributes
+ * <li>0 constructors
+ * <li>8 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addThreadBeanInfo(HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[12];
+ attributes[0] = new MBeanAttributeInfo("AllThreadIds", "[J",
+ "AllThreadIds", true, false, false);
+
+ attributes[1] = new MBeanAttributeInfo("CurrentThreadCpuTime",
+ Long.TYPE.getName(), "CurrentThreadCpuTime", true, false, false);
+
+ attributes[2] = new MBeanAttributeInfo("CurrentThreadUserTime",
+ Long.TYPE.getName(), "CurrentThreaduserTime", true, false,
+ false);
+
+ attributes[3] = new MBeanAttributeInfo("DaemonThreadCount",
+ Integer.TYPE.getName(), "DaemonThreadCount", true, false, false);
+
+ attributes[4] = new MBeanAttributeInfo("PeakThreadCount", Integer.TYPE
+ .getName(), "PeakThreadCount", true, false, false);
+
+ attributes[5] = new MBeanAttributeInfo("ThreadCount", Integer.TYPE
+ .getName(), "ThreadCount", true, false, false);
+
+ attributes[6] = new MBeanAttributeInfo("TotalStartedThreadCount",
+ Long.TYPE.getName(), "TotalStartedThreadCount", true, false,
+ false);
+
+ attributes[7] = new MBeanAttributeInfo("CurrentThreadCpuTimeSupported",
+ Boolean.TYPE.getName(), "CurrentThreadCpuTimeSupported", true,
+ false, true);
+
+ attributes[8] = new MBeanAttributeInfo(
+ "ThreadContentionMonitoringEnabled", Boolean.TYPE.getName(),
+ "ThreadContentionMonitoringEnabled", true, true, true);
+
+ attributes[9] = new MBeanAttributeInfo(
+ "ThreadContentionMonitoringSupported", Boolean.TYPE.getName(),
+ "ThreadContentionMonitoringSupported", true, false, true);
+
+ attributes[10] = new MBeanAttributeInfo("ThreadCpuTimeEnabled",
+ Boolean.TYPE.getName(), "ThreadCpuTimeEnabled", true, true,
+ true);
+
+ attributes[11] = new MBeanAttributeInfo("ThreadCpuTimeSupported",
+ Boolean.TYPE.getName(), "ThreadCpuTimeSupported", true, false,
+ true);
+
+ // Operations
+ MBeanOperationInfo[] operations = new MBeanOperationInfo[8];
+ MBeanParameterInfo[] nullParams = new MBeanParameterInfo[0];
+
+ operations[0] = new MBeanOperationInfo("findMonitorDeadlockedThreads",
+ "findMonitorDeadlockedThreads", nullParams, "[J",
+ MBeanOperationInfo.ACTION_INFO);
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("id", Long.TYPE.getName(), "id");
+ operations[1] = new MBeanOperationInfo("getThreadCpuTime",
+ "getThreadCpuTime", params, Long.TYPE.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("id", Long.TYPE.getName(), "id");
+ operations[2] = new MBeanOperationInfo("getThreadInfo",
+ "getThreadInfo", params, CompositeData.class.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("ids", "[J", "ids");
+ operations[3] = new MBeanOperationInfo("getThreadInfo",
+ "getThreadInfo", params, "[L"
+ + CompositeData.class.getName() + ";",
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[2];
+ params[0] = new MBeanParameterInfo("ids", "[J", "ids");
+ params[1] = new MBeanParameterInfo("maxDepth", Integer.TYPE
+ .getName(), "maxDepth");
+ operations[4] = new MBeanOperationInfo("getThreadInfo",
+ "getThreadInfo", params, "[L"
+ + CompositeData.class.getName() + ";",
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[2];
+ params[0] = new MBeanParameterInfo("id", Long.TYPE.getName(), "id");
+ params[1] = new MBeanParameterInfo("maxDepth", Integer.TYPE
+ .getName(), "maxDepth");
+ operations[5] = new MBeanOperationInfo("getThreadInfo",
+ "getThreadInfo", params, CompositeData.class.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("id", Long.TYPE.getName(), "id");
+ operations[6] = new MBeanOperationInfo("getThreadUserTime",
+ "getThreadUserTime", params, Long.TYPE.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ operations[7] = new MBeanOperationInfo("resetPeakThreadCount",
+ "resetPeakThreadCount", nullParams, Void.TYPE.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+
+ map.put(ThreadMXBean.class.getName(), new MBeanInfo(
+ ThreadMXBeanImpl.class.getName(), ThreadMXBeanImpl.class
+ .getName(), attributes, null, operations, null));
+ }
+
+ /**
+ * Creates the metadata for the {@link java.lang.management.RuntimeMXBean}.
+ * For this type of platform bean the metadata covers :
+ * <ul>
+ * <li>16 attributes
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addRuntimeBeanInfo(HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[16];
+ attributes[0] = new MBeanAttributeInfo("BootClassPath", String.class
+ .getName(), "BootClassPath", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("ClassPath", String.class
+ .getName(), "ClassPath", true, false, false);
+ attributes[2] = new MBeanAttributeInfo("InputArguments",
+ "[Ljava.lang.String;", "InputArguments", true, false, false);
+ attributes[3] = new MBeanAttributeInfo("LibraryPath", String.class
+ .getName(), "LibraryPath", true, false, false);
+ attributes[4] = new MBeanAttributeInfo("ManagementSpecVersion",
+ String.class.getName(), "ManagementSpecVersion", true, false,
+ false);
+ attributes[5] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[6] = new MBeanAttributeInfo("SpecName", String.class
+ .getName(), "SpecName", true, false, false);
+ attributes[7] = new MBeanAttributeInfo("SpecVendor", String.class
+ .getName(), "SpecVendor", true, false, false);
+ attributes[8] = new MBeanAttributeInfo("SpecVersion", String.class
+ .getName(), "SpecVersion", true, false, false);
+ attributes[9] = new MBeanAttributeInfo("StartTime",
+ Long.TYPE.getName(), "StartTime", true, false, false);
+ attributes[10] = new MBeanAttributeInfo("SystemProperties",
+ TabularData.class.getName(), "SystemProperties", true, false,
+ false);
+ attributes[11] = new MBeanAttributeInfo("Uptime", Long.TYPE.getName(),
+ "Uptime", true, false, false);
+ attributes[12] = new MBeanAttributeInfo("VmName", String.class
+ .getName(), "VmName", true, false, false);
+ attributes[13] = new MBeanAttributeInfo("VmVendor", String.class
+ .getName(), "VmVendor", true, false, false);
+ attributes[14] = new MBeanAttributeInfo("VmVersion", String.class
+ .getName(), "VmVersion", true, false, false);
+ attributes[15] = new MBeanAttributeInfo("BootClassPathSupported",
+ Boolean.TYPE.getName(), "BootClassPathSupported", true, false,
+ true);
+ map.put(RuntimeMXBean.class.getName(), new MBeanInfo(
+ RuntimeMXBeanImpl.class.getName(), RuntimeMXBeanImpl.class
+ .getName(), attributes, null, null, null));
+ }
+
+ /**
+ * Creates the metadata for the
+ * {@link java.lang.management.OperatingSystemMXBean}. For this type of
+ * platform bean the metadata covers :
+ * <ul>
+ * <li>4 attributes
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addOperatingSystemBeanInfo(
+ HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[4];
+ // Standard attributes...
+ attributes[0] = new MBeanAttributeInfo("Arch", String.class.getName(),
+ "Arch", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("AvailableProcessors",
+ Integer.TYPE.getName(), "AvailableProcessors", true, false,
+ false);
+ attributes[2] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[3] = new MBeanAttributeInfo("Version", String.class
+ .getName(), "Version", true, false, false);
+
+ // No operations
+
+ // No notifications
+
+ MBeanInfo mbeanInfo = new MBeanInfo(OperatingSystemMXBeanImpl.class
+ .getName(), OperatingSystemMXBeanImpl.class.getName(),
+ attributes, null, null, null);
+
+ map.put(OperatingSystemMXBean.class.getName(), mbeanInfo);
+ }
+
+ /**
+ * Creates the metadata for the
+ * {@link java.lang.management.MemoryPoolMXBean}. For this type of platform
+ * bean the metadata covers :
+ * <ul>
+ * <li>15 attributes
+ * <li>0 constructors
+ * <li>1 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addMemoryPoolBeanInfo(HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[15];
+ attributes[0] = new MBeanAttributeInfo("CollectionUsage",
+ CompositeData.class.getName(), "CollectionUsage", true, false,
+ false);
+ attributes[1] = new MBeanAttributeInfo("CollectionUsageThreshold",
+ Long.TYPE.getName(), "CollectionUsageThreshold", true, true,
+ false);
+ attributes[2] = new MBeanAttributeInfo("CollectionUsageThresholdCount",
+ Long.TYPE.getName(), "CollectionUsageThresholdCount", true,
+ false, false);
+ attributes[3] = new MBeanAttributeInfo("MemoryManagerNames",
+ "[Ljava.lang.String;", "MemoryManagerNames", true, false, false);
+ attributes[4] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[5] = new MBeanAttributeInfo("PeakUsage", CompositeData.class
+ .getName(), "PeakUsage", true, false, false);
+ attributes[6] = new MBeanAttributeInfo("Type", String.class.getName(),
+ "Type", true, false, false);
+ attributes[7] = new MBeanAttributeInfo("Usage", CompositeData.class
+ .getName(), "Usage", true, false, false);
+ attributes[8] = new MBeanAttributeInfo("UsageThreshold", Long.TYPE
+ .getName(), "UsageThreshold", true, true, false);
+ attributes[9] = new MBeanAttributeInfo("UsageThresholdCount", Long.TYPE
+ .getName(), "UsageThresholdCount", true, false, false);
+ attributes[10] = new MBeanAttributeInfo(
+ "CollectionUsageThresholdExceeded", Boolean.TYPE.getName(),
+ "CollectionUsageThresholdExceeded", true, false, true);
+ attributes[11] = new MBeanAttributeInfo(
+ "CollectionUsageThresholdSupported", Boolean.TYPE.getName(),
+ "CollectionUsageThresholdSupported", true, false, true);
+ attributes[12] = new MBeanAttributeInfo("UsageThresholdExceeded",
+ Boolean.TYPE.getName(), "UsageThresholdExceeded", true, false,
+ true);
+ attributes[13] = new MBeanAttributeInfo("UsageThresholdSupported",
+ Boolean.TYPE.getName(), "UsageThresholdSupported", true, false,
+ true);
+ attributes[14] = new MBeanAttributeInfo("Valid",
+ Boolean.TYPE.getName(), "Valid", true, false, true);
+
+ // Operations
+ MBeanOperationInfo[] operations = new MBeanOperationInfo[1];
+ MBeanParameterInfo[] params = new MBeanParameterInfo[0];
+ operations[0] = new MBeanOperationInfo("resetPeakUsage",
+ "resetPeakUsage", params, Void.TYPE.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+
+ MBeanInfo mbeanInfo = new MBeanInfo(MemoryPoolMXBeanImpl.class
+ .getName(), MemoryPoolMXBeanImpl.class.getName(), attributes,
+ null, operations, null);
+ map.put(MemoryPoolMXBean.class.getName(), mbeanInfo);
+ }
+
+ /**
+ * Creates the metadata for the {@link java.lang.management.MemoryMXBean}.
+ * For this type of platform bean the metadata covers :
+ * <ul>
+ * <li>4 attributes
+ * <li>0 constructors
+ * <li>1 operations
+ * <li>1 notification
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addMemoryBeanInfo(HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[4];
+ attributes[0] = new MBeanAttributeInfo("HeapMemoryUsage",
+ CompositeData.class.getName(), "HeapMemoryUsage", true, false,
+ false);
+ attributes[1] = new MBeanAttributeInfo("NonHeapMemoryUsage",
+ CompositeData.class.getName(), "NonHeapMemoryUsage", true,
+ false, false);
+ attributes[2] = new MBeanAttributeInfo(
+ "ObjectPendingFinalizationCount", Integer.TYPE.getName(),
+ "ObjectPendingFinalizationCount", true, false, false);
+ attributes[3] = new MBeanAttributeInfo("Verbose", Boolean.TYPE
+ .getName(), "Verbose", true, true, true);
+
+ // Operations
+ MBeanOperationInfo[] operations = new MBeanOperationInfo[1];
+ MBeanParameterInfo[] params = new MBeanParameterInfo[0];
+ operations[0] = new MBeanOperationInfo("gc", "gc", params, Void.TYPE
+ .getName(), MBeanOperationInfo.ACTION_INFO);
+
+ // Notifications
+ MBeanNotificationInfo[] notifications = new MBeanNotificationInfo[1];
+ String[] notifTypes = new String[2];
+ notifTypes[0] = MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED;
+ notifTypes[1] = MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED;
+ notifications[0] = new MBeanNotificationInfo(notifTypes,
+ javax.management.Notification.class.getName(),
+ "Memory Notification");
+
+ MBeanInfo mbeanInfo = new MBeanInfo(MemoryMXBeanImpl.class.getName(),
+ MemoryMXBeanImpl.class.getName(), attributes, null, operations,
+ notifications);
+ map.put(MemoryMXBean.class.getName(), mbeanInfo);
+ }
+
+ /**
+ * Creates the metadata for the
+ * {@link java.lang.management.MemoryManagerMXBean}. For this type of
+ * platform bean the metadata covers :
+ * <ul>
+ * <li>3 attribute
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addMemoryManagerBeanInfo(HashMap<String, MBeanInfo> map) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[3];
+ attributes[0] = new MBeanAttributeInfo("MemoryPoolNames",
+ "[Ljava.lang.String;", "MemoryPoolNames", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[2] = new MBeanAttributeInfo("Valid", Boolean.TYPE.getName(),
+ "Valid", true, false, true);
+
+ map.put(MemoryManagerMXBean.class.getName(), new MBeanInfo(
+ MemoryManagerMXBeanImpl.class.getName(),
+ MemoryManagerMXBeanImpl.class.getName(), attributes, null,
+ null, null));
+ }
+
+ /**
+ * Creates the metadata for the {@link java.util.logging.LoggingMXBean}.
+ * For this type of platform bean the metadata covers :
+ * <ul>
+ * <li>1 attribute
+ * <li>0 constructors
+ * <li>3 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param result
+ */
+ private static void addLoggingBeanInfo(HashMap<String, MBeanInfo> result) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[1];
+ attributes[0] = new MBeanAttributeInfo("LoggerNames",
+ "[Ljava.lang.String;", "LoggerNames", true, false, false);
+
+ // Operations
+ MBeanOperationInfo[] operations = new MBeanOperationInfo[3];
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("loggerName", String.class
+ .getName(), "loggerName");
+ operations[0] = new MBeanOperationInfo("getLoggerLevel",
+ "getLoggerLevel", params, String.class.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[1];
+ params[0] = new MBeanParameterInfo("loggerName", String.class
+ .getName(), "loggerName");
+ operations[1] = new MBeanOperationInfo("getParentLoggerName",
+ "getParentLoggerName", params, String.class.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+
+ {
+ MBeanParameterInfo[] params = new MBeanParameterInfo[2];
+ params[0] = new MBeanParameterInfo("loggerName", String.class
+ .getName(), "loggerName");
+ params[1] = new MBeanParameterInfo("levelName", String.class
+ .getName(), "levelName");
+ operations[2] = new MBeanOperationInfo("setLoggerLevel",
+ "setLoggerLevel", params, Void.TYPE.getName(),
+ MBeanOperationInfo.ACTION_INFO);
+ }
+ result.put(LoggingMXBean.class.getName(), new MBeanInfo(
+ LoggingMXBeanImpl.class.getName(), LoggingMXBeanImpl.class
+ .getName(), attributes, null, operations, null));
+ }
+
+ /**
+ * Creates the metadata for the {@link GarbageCollectorMXBean}. For this
+ * type of platform bean the metadata covers :
+ * <ul>
+ * <li>5 attributes
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param map
+ */
+ private static void addGarbageCollectorBeanInfo(
+ HashMap<String, MBeanInfo> map) {
+ // Note that GarbageCollectorMXBean extends MemoryManagerMXBean.
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[5];
+
+ // Standard attributes...
+ attributes[0] = new MBeanAttributeInfo("MemoryPoolNames",
+ "[Ljava.lang.String;", "MemoryPoolNames", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[2] = new MBeanAttributeInfo("Valid", Boolean.TYPE.getName(),
+ "Valid", true, false, true);
+ attributes[3] = new MBeanAttributeInfo("CollectionCount", Long.TYPE
+ .getName(), "CollectionCount", true, false, false);
+ attributes[4] = new MBeanAttributeInfo("CollectionTime", Long.TYPE
+ .getName(), "CollectionTime", true, false, false);
+
+ MBeanInfo mbeanInfo = new MBeanInfo(GarbageCollectorMXBeanImpl.class
+ .getName(), GarbageCollectorMXBeanImpl.class.getName(),
+ attributes, null, null, null);
+ map.put(GarbageCollectorMXBean.class.getName(), mbeanInfo);
+ }
+
+ /**
+ * Creates the metadata for the
+ * {@link java.lang.management.CompilationMXBean}. For this type of
+ * platform bean the metadata covers :
+ * <ul>
+ * <li>3 attributes
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param result
+ */
+ private static void addCompilationBeanInfo(HashMap<String, MBeanInfo> result) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[3];
+ attributes[0] = new MBeanAttributeInfo("Name", String.class.getName(),
+ "Name", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("TotalCompilationTime",
+ Long.TYPE.getName(), "TotalCompilationTime", true, false, false);
+ attributes[2] = new MBeanAttributeInfo(
+ "CompilationTimeMonitoringSupported", Boolean.TYPE.getName(),
+ "CompilationTimeMonitoringSupported", true, false, true);
+ result.put(CompilationMXBean.class.getName(), new MBeanInfo(
+ CompilationMXBeanImpl.class.getName(),
+ CompilationMXBeanImpl.class.getName(), attributes, null, null,
+ null));
+ }
+
+ /**
+ * Creates the metadata for the {@link ClassLoadingMXBean}bean. For this
+ * type of platform bean the metadata covers :
+ * <ul>
+ * <li>4 attributes
+ * <li>0 constructors
+ * <li>0 operations
+ * <li>0 notifications
+ * </ul>
+ *
+ * @param result
+ */
+ private static void addClassLoadingInfo(HashMap<String, MBeanInfo> result) {
+ // Attributes
+ MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[4];
+ attributes[0] = new MBeanAttributeInfo("LoadedClassCount", Integer.TYPE
+ .getName(), "LoadedClassCount", true, false, false);
+ attributes[1] = new MBeanAttributeInfo("TotalLoadedClassCount",
+ Long.TYPE.getName(), "TotalLoadedClassCount", true, false,
+ false);
+ attributes[2] = new MBeanAttributeInfo("UnloadedClassCount", Long.TYPE
+ .getName(), "UnloadedClassCount", true, false, false);
+ attributes[3] = new MBeanAttributeInfo("Verbose", Boolean.TYPE
+ .getName(), "Verbose", true, true, true);
+ result.put(ClassLoadingMXBean.class.getName(), new MBeanInfo(
+ ClassLoadingMXBeanImpl.class.getName(),
+ ClassLoadingMXBeanImpl.class.getName(), attributes, null, null,
+ null));
+ }
+
+ /**
+ * @return the singleton <code>MemoryMXBean</code> instance.
+ */
+ public static MemoryMXBeanImpl getMemoryBean() {
+ return MemoryMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return the singleton <code>ThreadMXBean</code> instance.
+ */
+ public static ThreadMXBeanImpl getThreadBean() {
+ return ThreadMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return the singleton <code>RuntimeMXBean</code> instance.
+ */
+ public static RuntimeMXBeanImpl getRuntimeBean() {
+ return RuntimeMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return the singleton <code>RuntimeMXBean</code> instance.
+ */
+ public static OperatingSystemMXBeanImpl getOperatingSystemBean() {
+ return OperatingSystemMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return the singleton <code>CompilationMXBean</code> if available.
+ */
+ public static CompilationMXBeanImpl getCompliationBean() {
+ return CompilationMXBeanImpl.getInstance();
+ }
+
+ /**
+ * @return the singleton <code>LoggingMXBean</code> instance.
+ */
+ public static LoggingMXBeanImpl getLoggingBean() {
+ return LoggingMXBeanImpl.getInstance();
+ }
+
+ /**
+ * Returns a list of all of the instances of {@link MemoryManagerMXBean}in
+ * this virtual machine. Owing to the dynamic nature of this kind of
+ * <code>MXBean</code>, it is possible that instances may be created or
+ * destroyed between the invocation and return of this method.
+ *
+ * @return a list of all known <code>MemoryManagerMXBean</code> s in this
+ * virtual machine.
+ */
+ public static List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
+ return new LinkedList<MemoryManagerMXBean>(getMemoryBean()
+ .getMemoryManagerMXBeans());
+ }
+
+ /**
+ * Returns a list of all of the instances of {@link MemoryPoolMXBean}in
+ * this virtual machine. Owing to the dynamic nature of this kind of
+ * <code>MXBean</code>, it is possible that instances may be created or
+ * destroyed between the invocation and return of this method.
+ *
+ * @return a list of all known <code>MemoryPoolMXBean</code> s in this
+ * virtual machine.
+ */
+ public static List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
+ List<MemoryPoolMXBean> result = new LinkedList<MemoryPoolMXBean>();
+ Iterator<MemoryManagerMXBean> iter = getMemoryManagerMXBeans()
+ .iterator();
+ while (iter.hasNext()) {
+ MemoryManagerMXBeanImpl b = (MemoryManagerMXBeanImpl) iter.next();
+ result.addAll(b.getMemoryPoolMXBeans());
+ }
+ return result;
+ }
+
+ /**
+ * Returns a list of all of the instances of {@link GarbageCollectorMXBean}
+ * in this virtual machine. Owing to the dynamic nature of this kind of
+ * <code>MXBean</code>, it is possible that instances may be created or
+ * destroyed between the invocation and return of this method.
+ *
+ * @return a list of all known <code>GarbageCollectorMXBean</code> s in
+ * this virtual machine.
+ */
+ public static List<GarbageCollectorMXBean> getGarbageCollectorMXBeans() {
+ List<GarbageCollectorMXBean> result = new LinkedList<GarbageCollectorMXBean>();
+ Iterator<MemoryManagerMXBean> iter = getMemoryBean()
+ .getMemoryManagerMXBeans().iterator();
+ while (iter.hasNext()) {
+ MemoryManagerMXBean b = iter.next();
+ if (b instanceof GarbageCollectorMXBean) {
+ result.add((GarbageCollectorMXBean) b);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException}if the {@link CompositeData}
+ * argument <code>cd</code> contains attributes that are not of the exact
+ * types specified in the <code>expectedTypes</code> argument. The
+ * attribute types of <code>cd</code> must also match the order of types
+ * in <code>expectedTypes</code>.
+ *
+ * @param cd
+ * a <code>CompositeData</code> object
+ * @param expectedNames
+ * an array of expected attribute names
+ * @param expectedTypes
+ * an array of type names
+ */
+ public static void verifyFieldTypes(CompositeData cd,
+ String[] expectedNames, String[] expectedTypes) {
+ Object[] allVals = cd.getAll(expectedNames);
+ // Check that the number of elements match
+ if (allVals.length != expectedTypes.length) {
+ throw new IllegalArgumentException(
+ "CompositeData does not contain the expected number of attributes.");
+ }
+
+ // Type of corresponding elements must be the same
+ for (int i = 0; i < allVals.length; i++) {
+ String expectedType = expectedTypes[i];
+ Object actualVal = allVals[i];
+ // It is permissible that a value in the CompositeData object is
+ // null in which case we cannot test its type. Move on.
+ if (actualVal == null) {
+ continue;
+ }
+ String actualType = actualVal.getClass().getName();
+ if (!actualType.equals(expectedType)) {
+ // Handle CompositeData and CompositeDataSupport
+ if (expectedType.equals(CompositeData.class.getName())) {
+ if (allVals[i] instanceof CompositeData) {
+ continue;
+ }
+ } else {
+ throw new IllegalArgumentException(
+ "CompositeData contains an attribute not of expected type. "
+ + "Expected " + expectedType + ", found "
+ + actualType);
+ }
+ }
+ }// end for
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException}if the {@link CompositeData}
+ * argument <code>cd</code> does not have any of the attributes named in
+ * the <code>expected</code> array of strings.
+ *
+ * @param cd
+ * a <code>CompositeData</code> object
+ * @param expected
+ * an array of attribute names expected in <code>cd</code>.
+ */
+ public static void verifyFieldNames(CompositeData cd, String[] expected) {
+ for (int i = 0; i < expected.length; i++) {
+ if (!cd.containsKey(expected[i])) {
+ throw new IllegalArgumentException(
+ "CompositeData object does not contain expected key : " //$NON-NLS-1$
+ + expected[i]);
+ }
+ }// end for all elements in expected
+ }
+
+ /**
+ * Throws an {@link IllegalArgumentException}if the {@link CompositeData}
+ * argument <code>cd</code> does not have the number of attributes
+ * specified in <code>i</code>.
+ *
+ * @param cd
+ * a <code>CompositeData</code> object
+ * @param i
+ * the number of expected attributes in <code>cd</code>
+ */
+ public static void verifyFieldNumber(CompositeData cd, int i) {
+ if (cd.values().size() != i) {
+ throw new IllegalArgumentException(
+ "CompositeData object does not have the expected number of attributes"); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * @param usage
+ * a {@link MemoryUsage}object.
+ * @return a {@link CompositeData}object that represents the supplied
+ * <code>usage</code> object.
+ */
+ public static CompositeData toMemoryUsageCompositeData(MemoryUsage usage) {
+ // Bail out early on null input.
+ if (usage == null) {
+ return null;
+ }
+
+ CompositeData result = null;
+ String[] names = { "init", "used", "committed", "max" };
+ Object[] values = { new Long(usage.getInit()),
+ new Long(usage.getUsed()), new Long(usage.getCommitted()),
+ new Long(usage.getMax()) };
+ CompositeType cType = getMemoryUsageCompositeType();
+ try {
+ result = new CompositeDataSupport(cType, names, values);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ return result;
+ }
+
+ /**
+ * @return an instance of {@link CompositeType}for the {@link MemoryUsage}
+ * class.
+ */
+ public static CompositeType getMemoryUsageCompositeType() {
+ if (MEMORYUSAGE_COMPOSITETYPE == null) {
+ String[] typeNames = { "init", "used", "committed", "max" };
+ String[] typeDescs = { "init", "used", "committed", "max" };
+ OpenType[] typeTypes = { SimpleType.LONG, SimpleType.LONG,
+ SimpleType.LONG, SimpleType.LONG };
+ try {
+ MEMORYUSAGE_COMPOSITETYPE = new CompositeType(MemoryUsage.class
+ .getName(), MemoryUsage.class.getName(), typeNames,
+ typeDescs, typeTypes);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ }
+ return MEMORYUSAGE_COMPOSITETYPE;
+ }
+
+ /**
+ * @param info
+ * a {@link java.lang.management.MemoryNotificationInfo}object.
+ * @return a {@link CompositeData}object that represents the supplied
+ * <code>info</code> object.
+ */
+ public static CompositeData toMemoryNotificationInfoCompositeData(
+ MemoryNotificationInfo info) {
+ // Bail out early on null input.
+ if (info == null) {
+ return null;
+ }
+
+ CompositeData result = null;
+ String[] names = { "poolName", "usage", "count" };
+ Object[] values = { new String(info.getPoolName()),
+ toMemoryUsageCompositeData(info.getUsage()),
+ new Long(info.getCount()) };
+ CompositeType cType = getMemoryNotificationInfoCompositeType();
+ try {
+ result = new CompositeDataSupport(cType, names, values);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ return result;
+ }
+
+ /**
+ * @return an instance of {@link CompositeType}for the
+ * {@link MemoryNotificationInfo}class.
+ */
+ private static CompositeType getMemoryNotificationInfoCompositeType() {
+ if (MEMORYNOTIFICATIONINFO_COMPOSITETYPE == null) {
+ String[] typeNames = { "poolName", "usage", "count" };
+ String[] typeDescs = { "poolName", "usage", "count" };
+ OpenType[] typeTypes = { SimpleType.STRING,
+ getMemoryUsageCompositeType(), SimpleType.LONG };
+ try {
+ MEMORYNOTIFICATIONINFO_COMPOSITETYPE = new CompositeType(
+ MemoryNotificationInfo.class.getName(),
+ MemoryNotificationInfo.class.getName(), typeNames,
+ typeDescs, typeTypes);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ }
+ return MEMORYNOTIFICATIONINFO_COMPOSITETYPE;
+ }
+
+ /**
+ * @param info
+ * a {@link ThreadInfo}object.
+ * @return a {@link CompositeData}object that represents the supplied
+ * <code>info</code> object.
+ */
+ public static CompositeData toThreadInfoCompositeData(ThreadInfo info) {
+ // Bail out early on null input.
+ if (info == null) {
+ return null;
+ }
+
+ CompositeData result = null;
+ StackTraceElement[] st = info.getStackTrace();
+ CompositeData[] stArray = new CompositeData[st.length];
+ for (int i = 0; i < st.length; i++) {
+ stArray[i] = toStackTraceElementCompositeData(st[i]);
+ }// end for
+
+ String[] names = { "threadId", "threadName", "threadState",
+ "suspended", "inNative", "blockedCount", "blockedTime",
+ "waitedCount", "waitedTime", "lockName", "lockOwnerId",
+ "lockOwnerName", "stackTrace" };
+ Object[] values = {
+ new Long(info.getThreadId()),
+ new String(info.getThreadName()),
+ new String(info.getThreadState().name()),
+ new Boolean(info.isSuspended()),
+ new Boolean(info.isInNative()),
+ new Long(info.getBlockedCount()),
+ new Long(info.getBlockedTime()),
+ new Long(info.getWaitedCount()),
+ new Long(info.getWaitedTime()),
+ info.getLockName() != null ? new String(info.getLockName())
+ : null,
+ new Long(info.getLockOwnerId()),
+ info.getLockOwnerName() != null ? new String(info
+ .getLockOwnerName()) : null, stArray };
+ CompositeType cType = getThreadInfoCompositeType();
+ try {
+ result = new CompositeDataSupport(cType, names, values);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ return result;
+ }
+
+ /**
+ * @param element
+ * a {@link StackTraceElement}object.
+ * @return a {@link CompositeData}object that represents the supplied
+ * <code>element</code> object.
+ */
+ public static CompositeData toStackTraceElementCompositeData(
+ StackTraceElement element) {
+ // Bail out early on null input.
+ if (element == null) {
+ return null;
+ }
+
+ CompositeData result = null;
+ String[] names = { "className", "methodName", "fileName", "lineNumber",
+ "nativeMethod" };
+
+ // A file name of null is permissable
+ String fileName = element.getFileName();
+ String fileNameValue = (fileName == null) ? null : new String(fileName);
+
+ Object[] values = { new String(element.getClassName()),
+ new String(element.getMethodName()), fileNameValue,
+ new Integer(element.getLineNumber()),
+ new Boolean(element.isNativeMethod()) };
+ CompositeType cType = getStackTraceElementCompositeType();
+ try {
+ result = new CompositeDataSupport(cType, names, values);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ return result;
+ }
+
+ /**
+ * @return an instance of {@link CompositeType}for the {@link ThreadInfo}
+ * class.
+ */
+ private static CompositeType getThreadInfoCompositeType() {
+ if (THREADINFO_COMPOSITETYPE == null) {
+ try {
+ String[] typeNames = { "threadId", "threadName", "threadState",
+ "suspended", "inNative", "blockedCount", "blockedTime",
+ "waitedCount", "waitedTime", "lockName", "lockOwnerId",
+ "lockOwnerName", "stackTrace" };
+ String[] typeDescs = { "threadId", "threadName", "threadState",
+ "suspended", "inNative", "blockedCount", "blockedTime",
+ "waitedCount", "waitedTime", "lockName", "lockOwnerId",
+ "lockOwnerName", "stackTrace" };
+ OpenType[] typeTypes = { SimpleType.LONG, SimpleType.STRING,
+ SimpleType.STRING, SimpleType.BOOLEAN,
+ SimpleType.BOOLEAN, SimpleType.LONG, SimpleType.LONG,
+ SimpleType.LONG, SimpleType.LONG, SimpleType.STRING,
+ SimpleType.LONG, SimpleType.STRING,
+ new ArrayType(1, getStackTraceElementCompositeType()) };
+ THREADINFO_COMPOSITETYPE = new CompositeType(ThreadInfo.class
+ .getName(), ThreadInfo.class.getName(), typeNames,
+ typeDescs, typeTypes);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ }
+ return THREADINFO_COMPOSITETYPE;
+ }
+
+ /**
+ * @return an instance of {@link CompositeType}for the
+ * {@link StackTraceElement}class.
+ */
+ private static CompositeType getStackTraceElementCompositeType() {
+ if (STACKTRACEELEMENT_COMPOSITETYPE == null) {
+ String[] typeNames = { "className", "methodName", "fileName",
+ "lineNumber", "nativeMethod" };
+ String[] typeDescs = { "className", "methodName", "fileName",
+ "lineNumber", "nativeMethod" };
+ OpenType[] typeTypes = { SimpleType.STRING, SimpleType.STRING,
+ SimpleType.STRING, SimpleType.INTEGER, SimpleType.BOOLEAN };
+ try {
+ STACKTRACEELEMENT_COMPOSITETYPE = new CompositeType(
+ StackTraceElement.class.getName(),
+ StackTraceElement.class.getName(), typeNames,
+ typeDescs, typeTypes);
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ }
+ return STACKTRACEELEMENT_COMPOSITETYPE;
+ }
+
+ /**
+ * Convenience method to converts an array of <code>String</code> to a
+ * <code>List<String></code>.
+ *
+ * @param data
+ * an array of <code>String</code>
+ * @return a new <code>List<String></code>
+ */
+ public static List<String> convertStringArrayToList(String[] data) {
+ List<String> result = new ArrayList<String>();
+ for (int i = 0; i < data.length; i++) {
+ result.add(data[i]);
+ }// end for
+ return result;
+ }
+
+ /**
+ * Receives an instance of a {@link TabularData}whose data is wrapping a
+ * <code>Map</code> and returns a new instance of <code>Map</code>
+ * containing the input information.
+ *
+ * @param data
+ * an instance of <code>TabularData</code> that may be mapped
+ * to a <code>Map</code>.
+ * @return a new {@link Map}containing the information originally wrapped
+ * in the <code>data</code> input.
+ * @throws IllegalArgumentException
+ * if <code>data</code> has a <code>CompositeType</code>
+ * that does not contain exactly two items (i.e. a key and a
+ * value).
+ */
+ @SuppressWarnings("unchecked")
+ public static Object convertTabularDataToMap(TabularData data) {
+ // Bail out early on null input.
+ if (data == null) {
+ return null;
+ }
+
+ Map<Object, Object> result = new HashMap<Object, Object>();
+ Set<String> cdKeySet = data.getTabularType().getRowType().keySet();
+ // The key set for the CompositeData instances comprising each row
+ // must contain only two elements.
+ if (cdKeySet.size() != 2) {
+ throw new IllegalArgumentException(
+ "TabularData's row type is not a CompositeType with two items.");
+ }
+ String[] keysArray = new String[2];
+ int count = 0;
+ Iterator<String> keysIt = cdKeySet.iterator();
+ while (keysIt.hasNext()) {
+ keysArray[count++] = keysIt.next();
+ }// end while
+
+ Collection<CompositeData> rows = data.values();
+ Iterator<CompositeData> rowIterator = rows.iterator();
+ while (rowIterator.hasNext()) {
+ CompositeData rowCD = rowIterator.next();
+ result.put(rowCD.get(keysArray[0]), rowCD.get(keysArray[1]));
+ }// end while a row to process
+ return result;
+ }
+
+ /**
+ * Return a new instance of type <code>T</code> from the supplied
+ * {@link CompositeData} object whose type maps to <code>T</code>.
+ *
+ * @param <T>
+ * the type of object wrapped by the <code>CompositeData</code>.
+ * @param data
+ * an instance of <code>CompositeData</code> that maps to an
+ * instance of <code>T</code>
+ * @param realClass
+ * the {@link Class} object for type <code>T</code>
+ * @return a new instance of <code>T</code>
+ * @throws NoSuchMethodException
+ * @throws SecurityException
+ * @throws InvocationTargetException
+ * @throws IllegalAccessException
+ * @throws IllegalArgumentException
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T convertFromCompositeData(CompositeData data,
+ Class<T> realClass) throws SecurityException,
+ NoSuchMethodException, IllegalArgumentException,
+ IllegalAccessException, InvocationTargetException {
+ // Bail out early on null input.
+ if (data == null) {
+ return null;
+ }
+
+ // See if the realClass has a static for method that takes a
+ // CompositeData and returns a new instance of T.
+ Method forMethod = realClass.getMethod("from",
+ new Class[] { CompositeData.class });
+ return (T) forMethod.invoke(null, data);
+ }
+
+ /**
+ * Receive data of the type specified in <code>openClass</code> and return
+ * it in an instance of the type specified in <code>realClass</code>.
+ *
+ * @param <T>
+ *
+ * @param data
+ * an instance of the type named <code>openTypeName</code>
+ * @param openClass
+ * @param realClass
+ * @return a new instance of the type <code>realTypeName</code> containing
+ * all the state in the input <code>data</code> object.
+ * @throws ClassNotFoundException
+ * @throws IllegalAccessException
+ * @throws InstantiationException
+ * @throws InvocationTargetException
+ * @throws NoSuchMethodException
+ * @throws IllegalArgumentException
+ * @throws SecurityException
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T convertFromOpenType(Object data, Class<?> openClass,
+ Class<T> realClass) throws ClassNotFoundException,
+ InstantiationException, IllegalAccessException, SecurityException,
+ IllegalArgumentException, NoSuchMethodException,
+ InvocationTargetException {
+ // Bail out early on null input.
+ if (data == null) {
+ return null;
+ }
+
+ T result = null;
+
+ if (openClass.isArray() && realClass.isArray()) {
+ Class openElementClass = openClass.getComponentType();
+ Class<?> realElementClass = realClass.getComponentType();
+
+ Object[] dataArray = (Object[]) data;
+ result = (T) Array.newInstance(realElementClass, dataArray.length);
+ for (int i = 0; i < Array.getLength(result); i++) {
+ Array.set(result, i, convertFromOpenType(dataArray[i],
+ openElementClass, realElementClass));
+ }// end for
+ } else if (openClass.equals(CompositeData.class)) {
+ result = ManagementUtils.convertFromCompositeData(
+ (CompositeData) data, realClass);
+ } else if (openClass.equals(TabularData.class)) {
+ if (realClass.equals(Map.class)) {
+ result = (T) ManagementUtils
+ .convertTabularDataToMap((TabularData) data);
+ }
+ } else if (openClass.equals(String[].class)) {
+ if (realClass.equals(List.class)) {
+ result = (T) ManagementUtils
+ .convertStringArrayToList((String[]) data);
+ }
+ } else if (openClass.equals(String.class)) {
+ if (realClass.equals(MemoryType.class)) {
+ result = (T) ManagementUtils
+ .convertStringToMemoryType((String) data);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Convenience method that receives a string representation of a
+ * <code>MemoryType</code> instance and returns the actual
+ * <code>MemoryType</code> that corresponds to that value.
+ *
+ * @param data
+ * a string
+ * @return if <code>data</code> can be used to obtain an instance of
+ * <code>MemoryType</code> then a <code>MemoryType</code>,
+ * otherwise <code>null</code>.
+ */
+ private static MemoryType convertStringToMemoryType(String data) {
+ MemoryType result = null;
+ try {
+ result = MemoryType.valueOf(data);
+ } catch (IllegalArgumentException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ }
+ return result;
+ }
+
+ /**
+ * Convenience method to convert an object, <code>data</code> from its
+ * Java type <code>realClass</code> to the specified open MBean type
+ * <code>openClass</code>.
+ *
+ * @param <T>
+ * the open MBean class
+ * @param data
+ * the object to be converted
+ * @param openClass
+ * the open MBean class
+ * @param realClass
+ * the real Java type of <code>data</code>
+ * @return a new instance of type <code>openClass</code>
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T convertToOpenType(Object data, Class<T> openClass,
+ Class<?> realClass) {
+ // Bail out early on null input.
+ if (data == null) {
+ return null;
+ }
+
+ T result = null;
+
+ if (openClass.isArray() && realClass.isArray()) {
+ Class<?> openElementClass = openClass.getComponentType();
+ Class<?> realElementClass = realClass.getComponentType();
+
+ Object[] dataArray = (Object[]) data;
+ result = (T) Array.newInstance(openElementClass, dataArray.length);
+ for (int i = 0; i < Array.getLength(result); i++) {
+ Array.set(result, i, convertToOpenType(dataArray[i],
+ openElementClass, realElementClass));
+ }// end for
+ } else if (openClass.equals(CompositeData.class)) {
+ if (realClass.equals(ThreadInfo.class)) {
+ result = (T) ManagementUtils
+ .toThreadInfoCompositeData((ThreadInfo) data);
+ } else if (realClass.equals(MemoryUsage.class)) {
+ result = (T) ManagementUtils
+ .toMemoryUsageCompositeData((MemoryUsage) data);
+ }
+ } else if (openClass.equals(TabularData.class)) {
+ if (realClass.equals(Map.class)) {
+ result = (T) ManagementUtils
+ .toSystemPropertiesTabularData((Map) data);
+ }
+ } else if (openClass.equals(String[].class)) {
+ if (realClass.equals(List.class)) {
+ result = (T) ManagementUtils.convertListToArray((List) data,
+ openClass, openClass.getComponentType());
+ }
+ } else if (openClass.equals(String.class)) {
+ if (realClass.isEnum()) {
+ result = (T) ((Enum) data).name();
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Convenience method to convert a {@link List} instance to an instance of
+ * an array. The element type of the returned array will be of the same type
+ * as the <code>List</code> component values.
+ *
+ * @param <T>
+ * the array type named <code>arrayType</code>
+ * @param <E>
+ * the type of the elements in the array,
+ * <code>elementType</code>
+ * @param list
+ * the <code>List</code> to be converted
+ * @param arrayType
+ * the array type
+ * @param elementType
+ * the type of the array's elements
+ * @return a new instance of <code>arrayType</code> initialised with the
+ * data stored in <code>list</code>
+ */
+ @SuppressWarnings("unchecked")
+ private static <T, E> T convertListToArray(List<E> list,
+ Class<T> arrayType, Class<E> elementType) {
+ T result = (T) Array.newInstance(elementType, list.size());
+ Iterator<E> it = list.iterator();
+ int count = 0;
+ while (it.hasNext()) {
+ E element = it.next();
+ Array.set(result, count++, element);
+ }
+ return result;
+ }
+
+ /**
+ * @param propsMap
+ * a <code>Map<String, String%gt;</code> of the system
+ * properties.
+ * @return the system properties (e.g. as obtained from
+ * {@link RuntimeMXBean#getSystemProperties()}) wrapped in a
+ * {@link TabularData}.
+ */
+ public static TabularData toSystemPropertiesTabularData(
+ Map<String, String> propsMap) {
+ // Bail out early on null input.
+ if (propsMap == null) {
+ return null;
+ }
+
+ TabularData result = null;
+ try {
+ // Obtain the row type for the TabularType
+ String[] rtItemNames = { "key", "value" };
+ String[] rtItemDescs = { "key", "value" };
+ OpenType[] rtItemTypes = { SimpleType.STRING, SimpleType.STRING };
+
+ CompositeType rowType = new CompositeType(propsMap.getClass()
+ .getName(), propsMap.getClass().getName(), rtItemNames,
+ rtItemDescs, rtItemTypes);
+
+ // Obtain the required TabularType
+ TabularType sysPropsType = new TabularType(propsMap.getClass()
+ .getName(), propsMap.getClass().getName(), rowType,
+ new String[] { "key" });
+
+ // Create an empty TabularData
+ result = new TabularDataSupport(sysPropsType);
+
+ // Take each entry out of the input propsMap, put it into a new
+ // instance of CompositeData and put into the TabularType
+ Set<String> keys = propsMap.keySet();
+ for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
+ String propKey = iter.next();
+ String propVal = propsMap.get(propKey);
+ result.put(new CompositeDataSupport(rowType, rtItemNames,
+ new String[] { propKey, propVal }));
+ }// end for
+ } catch (OpenDataException e) {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ result = null;
+ }
+ return result;
+ }
+
+ /**
+ * Convenience method that sets out to return the {@link Class}object for
+ * the specified type named <code>name</code>. Unlike the
+ * {@link Class#forName(java.lang.String)}method, this will work even for
+ * primitive types.
+ *
+ * @param name
+ * the name of a Java type
+ * @return the <code>Class</code> object for the type <code>name</code>
+ * @throws ClassNotFoundException
+ * if <code>name</code> does not correspond to any known type
+ * (including primitive types).
+ */
+ public static Class getClassMaybePrimitive(String name)
+ throws ClassNotFoundException {
+ Class result = null;
+
+ try {
+ result = Class.forName(name);
+ } catch (ClassNotFoundException e) {
+ if (name.equals(boolean.class.getName())) {
+ result = boolean.class;
+ } else if (name.equals(char.class.getName())) {
+ result = char.class;
+ } else if (name.equals(byte.class.getName())) {
+ result = byte.class;
+ } else if (name.equals(short.class.getName())) {
+ result = short.class;
+ } else if (name.equals(int.class.getName())) {
+ result = int.class;
+ } else if (name.equals(long.class.getName())) {
+ result = long.class;
+ } else if (name.equals(float.class.getName())) {
+ result = float.class;
+ } else if (name.equals(double.class.getName())) {
+ result = double.class;
+ } else if (name.equals(void.class.getName())) {
+ result = void.class;
+ } else {
+ if (ManagementUtils.VERBOSE_MODE) {
+ e.printStackTrace(System.err);
+ }// end if
+ // Rethrow the original ClassNotFoundException
+ throw e;
+ }// end else
+ }// end catch
+ return result;
+ }
+
+ /**
+ * Convenience method to determine if the <code>wrapper</code>
+ * <code>Class</code>
+ * object is really the wrapper class for the
+ * <code>primitive</code> <code>Class</code> object.
+ *
+ * @param wrapper
+ * @param primitive
+ * @return <code>true</code> if the <code>wrapper</code> class is the
+ * wrapper class for <code>primitive</code>. Otherwise
+ * <code>false</code>.
+ */
+ public static boolean isWrapperClass(Class<? extends Object> wrapper,
+ Class primitive) {
+ boolean result = true;
+ if (primitive.equals(boolean.class) && !wrapper.equals(Boolean.class)) {
+ result = false;
+ } else if (primitive.equals(char.class)
+ && !wrapper.equals(Character.class)) {
+ result = false;
+ } else if (primitive.equals(byte.class) && !wrapper.equals(Byte.class)) {
+ result = false;
+ } else if (primitive.equals(short.class)
+ && !wrapper.equals(Short.class)) {
+ result = false;
+ } else if (primitive.equals(int.class)
+ && !wrapper.equals(Integer.class)) {
+ result = false;
+ } else if (primitive.equals(long.class) && !wrapper.equals(Long.class)) {
+ result = false;
+ } else if (primitive.equals(float.class)
+ && !wrapper.equals(Float.class)) {
+ result = false;
+ } else if (primitive.equals(double.class)
+ && !wrapper.equals(Double.class)) {
+ result = false;
+ }
+
+ return result;
+ }
+
+ /**
+ * Convenience method that returns a boolean indication of whether or not
+ * concrete instances of the the supplied interface type
+ * <code>mxbeanInterface</code> should also be implementors of the
+ * interface <code>javax.management.NotificationEmitter</code>.
+ *
+ * @param <T>
+ * @param mxbeanInterface
+ * @return <code>true</code> if instances of type
+ * <code>mxbeanInterface</code> should also implement
+ * <code>javax.management.NotificationEmitter</code>. Otherwise,
+ * <code>false</code>.
+ */
+ public static <T> boolean isANotificationEmitter(Class<T> mxbeanInterface) {
+ boolean result = false;
+ MBeanInfo info = getMBeanInfo(mxbeanInterface.getName());
+ if (info != null) {
+ MBeanNotificationInfo[] notifications = info.getNotifications();
+ if ((notifications != null) && (notifications.length > 0)) {
+ result = true;
+ }
+ }
+ return result;
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/ManagementUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryMXBeanImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryMXBeanImpl.java?view=auto&rev=495839
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryMXBeanImpl.java (added)
+++ harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryMXBeanImpl.java Fri Jan 12 21:08:48 2007
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.lang.management;
+
+import java.lang.management.ManagementPermission;
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryUsage;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanNotificationInfo;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+
+/**
+ * Runtime type for {@link MemoryMXBean}.
+ * <p>
+ * Implementation note. This type of bean is both dynamic and a notification
+ * emitter. The dynamic behaviour comes courtesy of the
+ * {@link com.ibm.lang.management.DynamicMXBeanImpl} superclass while the
+ * notifying behaviour uses a delegation approach to a private member that
+ * implements the {@link javax.management.NotificationEmitter} interface.
+ * Because multiple inheritance is not supported in Java it was a toss up which
+ * behaviour would be based on inheritence and which would use delegation. Every
+ * other <code>*MXBeanImpl</code> class in this package inherits from the
+ * abstract base class <code>DynamicMXBeanImpl</code> so that seemed to be the
+ * natural approach for this class too. By choosing not to make this class a
+ * subclass of {@link javax.management.NotificationBroadcasterSupport}, the
+ * protected
+ * <code>handleNotification(javax.management.NotificationListener, javax.management.Notification, java.lang.Object)</code>
+ * method cannot be overridden for any custom notification behaviour. However,
+ * taking the agile mantra of <b>YAGNI </b> to heart, it was decided that the
+ * default implementation of that method will suffice until new requirements
+ * prove otherwise.
+ * </p>
+ *
+ * @since 1.5
+ */
+public final class MemoryMXBeanImpl extends DynamicMXBeanImpl implements
+ java.lang.management.MemoryMXBean, NotificationEmitter {
+
+ /**
+ * The delegate for all notification management.
+ */
+ private NotificationBroadcasterSupport notifier = new NotificationBroadcasterSupport();
+
+ private static MemoryMXBeanImpl instance = new MemoryMXBeanImpl();
+
+ private List<MemoryManagerMXBean> memoryManagerList;
+
+ /**
+ * Constructor intentionally private to prevent instantiation by others.
+ * Sets the metadata for this bean.
+ */
+ private MemoryMXBeanImpl() {
+ setMBeanInfo(ManagementUtils
+ .getMBeanInfo(java.lang.management.MemoryMXBean.class.getName()));
+ memoryManagerList = new LinkedList<MemoryManagerMXBean>();
+ createMemoryManagers();
+ }
+
+ /**
+ * Singleton accessor method.
+ *
+ * @return the <code>ClassLoadingMXBeanImpl</code> singleton.
+ */
+ static MemoryMXBeanImpl getInstance() {
+ return instance;
+ }
+
+ /**
+ * Instantiates MemoryManagerMXBean and GarbageCollectorMXBean instance(s)
+ * for the current VM configuration and stores them in memoryManagerList.
+ */
+ private native void createMemoryManagers();
+
+ /**
+ * A helper method called from within the native
+ * {@link #createMemoryManagers()} method to construct new instances of
+ * MemoryManagerMXBean and GarbageCollectorMXBean and add them to the
+ * {@link #memoryManagerList}.
+ *
+ * @param name
+ * the name of the corresponding memory manager
+ * @param internalID
+ * numerical identifier associated with the memory manager for
+ * the benefit of the VM
+ * @param isGC
+ * boolean indication of the memory manager type.
+ * <code>true</code> indicates that the runtime type of the
+ * object to be created is
+ * <code>GarbageCollectorMXBeanImpl</code> while
+ * <code>false</code> indicates a
+ * <code>MemoryManagerMXBeanImpl</code>
+ */
+ @SuppressWarnings("unused")
+ // IMPORTANT: for use by VM
+ private void createMemoryManagerHelper(String name, int internalID,
+ boolean isGC) {
+ if (isGC) {
+ memoryManagerList.add(new GarbageCollectorMXBeanImpl(name,
+ internalID, this));
+ } else {
+ memoryManagerList.add(new MemoryManagerMXBeanImpl(name, internalID,
+ this));
+ }
+ }
+
+ /**
+ * Retrieves the list of memory manager beans in the system.
+ *
+ * @return the list of <code>MemoryManagerMXBean</code> instances
+ */
+ List<MemoryManagerMXBean> getMemoryManagerMXBeans() {
+ return memoryManagerList;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#gc()
+ */
+ public void gc() {
+ System.gc();
+ }
+
+ /**
+ * @return an instance of {@link MemoryUsage}which can be interrogated by
+ * the caller.
+ * @see #getHeapMemoryUsage()
+ */
+ private native MemoryUsage getHeapMemoryUsageImpl();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#getHeapMemoryUsage()
+ */
+ public MemoryUsage getHeapMemoryUsage() {
+ return this.getHeapMemoryUsageImpl();
+ }
+
+ /**
+ * @return an instance of {@link MemoryUsage}which can be interrogated by
+ * the caller.
+ * @see #getNonHeapMemoryUsage()
+ */
+ private native MemoryUsage getNonHeapMemoryUsageImpl();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#getNonHeapMemoryUsage()
+ */
+ public MemoryUsage getNonHeapMemoryUsage() {
+ return this.getNonHeapMemoryUsageImpl();
+ }
+
+ /**
+ * @return the number of objects awaiting finalization.
+ * @see #getObjectPendingFinalizationCount()
+ */
+ private native int getObjectPendingFinalizationCountImpl();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#getObjectPendingFinalizationCount()
+ */
+ public int getObjectPendingFinalizationCount() {
+ return this.getObjectPendingFinalizationCountImpl();
+ }
+
+ /**
+ * @return <code>true</code> if verbose output is being produced ;
+ * <code>false</code> otherwise.
+ * @see #isVerbose()
+ */
+ private native boolean isVerboseImpl();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#isVerbose()
+ */
+ public boolean isVerbose() {
+ return this.isVerboseImpl();
+ }
+
+ /**
+ * @param value
+ * <code>true</code> enables verbose output ;
+ * <code>false</code> disables verbose output.
+ * @see #setVerbose(boolean)
+ */
+ private native void setVerboseImpl(boolean value);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryMXBean#setVerbose(boolean)
+ */
+ public void setVerbose(boolean value) {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkPermission(new ManagementPermission("control"));
+ }
+ this.setVerboseImpl(value);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.management.NotificationEmitter#removeNotificationListener(javax.management.NotificationListener,
+ * javax.management.NotificationFilter, java.lang.Object)
+ */
+ public void removeNotificationListener(NotificationListener listener,
+ NotificationFilter filter, Object handback)
+ throws ListenerNotFoundException {
+ notifier.removeNotificationListener(listener, filter, handback);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.management.NotificationBroadcaster#addNotificationListener(javax.management.NotificationListener,
+ * javax.management.NotificationFilter, java.lang.Object)
+ */
+ public void addNotificationListener(NotificationListener listener,
+ NotificationFilter filter, Object handback)
+ throws IllegalArgumentException {
+ notifier.addNotificationListener(listener, filter, handback);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.management.NotificationBroadcaster#removeNotificationListener(javax.management.NotificationListener)
+ */
+ public void removeNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ notifier.removeNotificationListener(listener);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see javax.management.NotificationBroadcaster#getNotificationInfo()
+ */
+ public MBeanNotificationInfo[] getNotificationInfo() {
+ // We know what kinds of notifications we can emit whereas the
+ // notifier delegate does not. So, for this method, no delegating.
+ // Instead respond using our own metadata.
+ return this.getMBeanInfo().getNotifications();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * Send notifications to registered listeners. This will be called when
+ * either of the following situations occur: <ol><li> With the method
+ * {@link java.lang.management.MemoryPoolMXBean#isUsageThresholdSupported()}
+ * returning <code> true </code> , a memory pool increases its size and, in
+ * doing so, reaches or exceeds the usage threshold value. In this case the
+ * notification type will be
+ * {@link MemoryNotificationInfo#MEMORY_THRESHOLD_EXCEEDED}. <li> With the
+ * method
+ * {@link java.lang.management.MemoryPoolMXBean#isCollectionUsageThresholdSupported()}
+ * returning <code> true </code> , a garbage-collected memory pool has
+ * reached or surpassed the collection usage threshold value after a system
+ * garbage collection has taken place. In this case the notification type
+ * will be
+ * {@link MemoryNotificationInfo#MEMORY_COLLECTION_THRESHOLD_EXCEEDED}.
+ * </ol>
+ *
+ * @param notification For this type of bean the user data will consist of a
+ * {@link CompositeData}instance that represents a
+ * {@link MemoryNotificationInfo}object.
+ */
+ public void sendNotification(Notification notification) {
+ notifier.sendNotification(notification);
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryMXBeanImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryManagerMXBeanImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryManagerMXBeanImpl.java?view=auto&rev=495839
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryManagerMXBeanImpl.java (added)
+++ harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryManagerMXBeanImpl.java Fri Jan 12 21:08:48 2007
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.lang.management;
+
+import java.lang.management.MemoryManagerMXBean;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Runtime type for {@link MemoryManagerMXBean}
+ *
+ * @since 1.5
+ */
+public class MemoryManagerMXBeanImpl extends DynamicMXBeanImpl implements
+ MemoryManagerMXBean {
+ protected final String name;
+
+ protected final int id;
+
+ private List<MemoryPoolMXBean> managedPoolList;
+
+ /**
+ * Sets the metadata for this bean.
+ *
+ * @param name
+ * @param id
+ * @param memBean
+ */
+ MemoryManagerMXBeanImpl(String name, int id, MemoryMXBeanImpl memBean) {
+ this.name = name;
+ this.id = id;
+ initializeInfo();
+ managedPoolList = new LinkedList<MemoryPoolMXBean>();
+ createMemoryPools(id, memBean);
+ }
+
+ /**
+ *
+ */
+ protected void initializeInfo() {
+ setMBeanInfo(ManagementUtils.getMBeanInfo(MemoryManagerMXBean.class
+ .getName()));
+ }
+
+ /**
+ * Instantiate the MemoryPoolMXBeans representing the memory managed by this
+ * manager, and store them in the managedPoolList.
+ *
+ * @param managerID
+ * @param memBean
+ */
+ private native void createMemoryPools(int managerID,
+ MemoryMXBeanImpl memBean);
+
+ /**
+ * A helper method called from within the native
+ * {@link #createMemoryPools(int, MemoryMXBeanImpl)} method to construct new
+ * MemoryPoolMXBeans representing memory managed by this manager and add
+ * them to the {@link #managedPoolList}.
+ *
+ * @param name
+ * the name of the corresponding memory pool
+ * @param isHeap
+ * boolean indication of the memory pool type. <code>true</code>
+ * indicates that the memory is heap memory while
+ * <code>false</code> indicates non-heap memory
+ * @param internalID
+ * numerical identifier associated with the memory pool for the
+ * benefit of the VM
+ * @param memBean
+ * the {@link MemoryMXBeanImpl} that will send event
+ * notifications related to this memory pool
+ */
+ @SuppressWarnings("unused")
+ // IMPORTANT: for use by VM
+ private void createMemoryPoolHelper(String name, boolean isHeap,
+ int internalID, MemoryMXBeanImpl memBean) {
+ managedPoolList.add(new MemoryPoolMXBeanImpl(name,
+ isHeap ? MemoryType.HEAP : MemoryType.NON_HEAP, internalID,
+ memBean));
+ }
+
+ /**
+ * Retrieves the list of memory pool beans managed by this manager.
+ *
+ * @return the list of <code>MemoryPoolMXBean</code> instances
+ */
+ List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
+ return managedPoolList;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryManagerMXBean#getMemoryPoolNames()
+ */
+ public String[] getMemoryPoolNames() {
+ String[] names = new String[managedPoolList.size()];
+ int idx = 0;
+ Iterator<MemoryPoolMXBean> iter = managedPoolList.iterator();
+ while (iter.hasNext()) {
+ names[idx++] = iter.next().getName();
+ }
+ return names;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryManagerMXBean#getName()
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ /**
+ * @return <code>true</code> if the memory manager is still valid in the
+ * virtual machine ; otherwise <code>false</code>.
+ * @see #isValid()
+ */
+ private native boolean isValidImpl();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.management.MemoryManagerMXBean#isValid()
+ */
+ public boolean isValid() {
+ return this.isValidImpl();
+ }
+}
Propchange: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryManagerMXBeanImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryNotificationThread.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryNotificationThread.java?view=auto&rev=495839
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryNotificationThread.java (added)
+++ harmony/enhanced/classlib/trunk/modules/lang-management/src/main/java/com/ibm/lang/management/MemoryNotificationThread.java Fri Jan 12 21:08:48 2007
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.ibm.lang.management;
+
+import java.lang.management.MemoryNotificationInfo;
+import java.lang.management.MemoryUsage;
+
+import javax.management.Notification;
+
+/**
+ * A thread that monitors and dispatches memory usage notifications from an
+ * internal queue.
+ *
+ * @since 1.5
+ */
+class MemoryNotificationThread extends Thread {
+
+ private MemoryMXBeanImpl memBean;
+
+ private MemoryPoolMXBeanImpl memPool;
+
+ int internalID;
+
+ /**
+ * Basic constructor
+ *
+ * @param mem
+ * The memory bean to send notifications through
+ * @param myPool
+ * The memory pool bean we are sending notifications on behalf of
+ * @param id
+ * The internal ID of the notification queue being monitored
+ */
+ MemoryNotificationThread(MemoryMXBeanImpl mem, MemoryPoolMXBeanImpl myPool,
+ int id) {
+ memBean = mem;
+ memPool = myPool;
+ internalID = id;
+ }
+
+ /**
+ * Register a shutdown handler that will signal this thread to terminate,
+ * then enter the native that services an internal notification queue.
+ */
+ public void run() {
+ Thread myShutdownNotifier = new MemoryNotificationThreadShutdown(this);
+ try {
+ Runtime.getRuntime().addShutdownHook(myShutdownNotifier);
+ } catch (IllegalStateException e) {
+ /*
+ * if by chance we are already shutting down when we try to register
+ * the shutdown hook, allow this thread to terminate silently
+ */
+ return;
+ }
+ processNotificationLoop(internalID);
+ }
+
+ /**
+ * Process notifications on an internal VM queue until a shutdown request is
+ * received.
+ *
+ * @param internalID
+ * The internal ID of the queue to service
+ */
+ private native void processNotificationLoop(int internalID);
+
+ /**
+ * A helper method called from within the native
+ * {@link #processNotificationLoop(int)} method to construct and dispatch
+ * notification objects.
+ *
+ * @param min
+ * the initial amount in bytes of memory that can be allocated by
+ * this virtual machine
+ * @param used
+ * the number of bytes currently used for memory
+ * @param committed
+ * the number of bytes of committed memory
+ * @param max
+ * the maximum number of bytes that can be used for memory
+ * management purposes
+ * @param count
+ * the number of times that the memory usage of the memory pool
+ * in question has met or exceeded the relevant threshold
+ * @param sequenceNumber
+ * the sequence identifier of the current notification
+ * @param isCollectionUsageNotification
+ * a <code>boolean</code> indication of whether or not the new
+ * notification is as a result of the collection threshold being
+ * exceeded. If this value is <code>false</code> then the
+ * implication is that a memory threshold has been exceeded.
+ */
+ @SuppressWarnings("unused")
+ // IMPORTANT: for use by VM
+ private void dispatchNotificationHelper(long min, long used,
+ long committed, long max, long count, long sequenceNumber,
+ boolean isCollectionUsageNotification) {
+ MemoryNotificationInfo info = new MemoryNotificationInfo(memPool
+ .getName(), new MemoryUsage(min, used, committed, max), count);
+ Notification n = new Notification(
+ isCollectionUsageNotification ? MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED
+ : MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED,
+ "java.lang:type=Memory", sequenceNumber);
+ n.setUserData(ManagementUtils
+ .toMemoryNotificationInfoCompositeData(info));
+ memBean.sendNotification(n);
+ }
+}