1 /*
   2  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Sun designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Sun in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22  * CA 95054 USA or visit www.sun.com if you need additional information or
  23  * have any questions.
  24  */
  25 
  26 package java.lang.management;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collections;
  30 import java.util.List;
  31 import java.util.HashSet;
  32 import java.util.Set;
  33 import java.util.logging.LoggingMXBean;
  34 import java.util.logging.LogManager;
  35 import java.nio.BufferPoolMXBean;
  36 import javax.management.MBeanServerConnection;
  37 import javax.management.MalformedObjectNameException;
  38 import javax.management.ObjectName;
  39 
  40 import com.sun.management.HotSpotDiagnosticMXBean;
  41 import com.sun.management.UnixOperatingSystemMXBean;
  42 
  43 import sun.management.ManagementFactoryHelper;
  44 
  45 /**
  46  * This enum class defines the list of platform components
  47  * that provides monitoring and management support.
  48  * Each enum represents one MXBean interface. A MXBean
  49  * instance could implement one or more MXBean interfaces.
  50  *
  51  * For example, com.sun.management.GarbageCollectorMXBean
  52  * extends java.lang.management.GarbageCollectorMXBean
  53  * and there is one set of garbage collection MXBean instances,
  54  * each of which implements both c.s.m. and j.l.m. interfaces.
  55  * There are two separate enums GARBAGE_COLLECTOR
  56  * and SUN_GARBAGE_COLLECTOR so that ManagementFactory.getPlatformMXBeans(Class)
  57  * will return the list of MXBeans of the specified type.
  58  *
  59  * To add a new MXBean interface for the Java platform,
  60  * add a new enum constant and implement the MXBeanFetcher.
  61  */
  62 enum PlatformComponent {
  63 
  64     /**
  65      * Class loading system of the Java virtual machine.
  66      */
  67     CLASS_LOADING(
  68         "java.lang.management.ClassLoadingMXBean",
  69         "java.lang", "ClassLoading", defaultKeyProperties(),
  70         new MXBeanFetcher<ClassLoadingMXBean>() {
  71             public List<ClassLoadingMXBean> getMXBeans() {
  72                 return Collections.singletonList(ManagementFactoryHelper.getClassLoadingMXBean());
  73             }
  74         }),
  75 
  76     /**
  77      * Compilation system of the Java virtual machine.
  78      */
  79     COMPILATION(
  80         "java.lang.management.CompilationMXBean",
  81         "java.lang", "Compilation", defaultKeyProperties(),
  82         new MXBeanFetcher<CompilationMXBean>() {
  83             public List<CompilationMXBean> getMXBeans() {
  84                 CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
  85                 if (m == null) {
  86                    return Collections.emptyList();
  87                 } else {
  88                    return Collections.singletonList(m);
  89                 }
  90             }
  91         }),
  92 
  93     /**
  94      * Memory system of the Java virtual machine.
  95      */
  96     MEMORY(
  97         "java.lang.management.MemoryMXBean",
  98         "java.lang", "Memory", defaultKeyProperties(),
  99         new MXBeanFetcher<MemoryMXBean>() {
 100             public List<MemoryMXBean> getMXBeans() {
 101                 return Collections.singletonList(ManagementFactoryHelper.getMemoryMXBean());
 102             }
 103         }),
 104 
 105     /**
 106      * Garbage Collector in the Java virtual machine.
 107      */
 108     GARBAGE_COLLECTOR(
 109         "java.lang.management.GarbageCollectorMXBean",
 110         "java.lang", "GarbageCollector", keyProperties("name"),
 111         new MXBeanFetcher<GarbageCollectorMXBean>() {
 112             public List<GarbageCollectorMXBean> getMXBeans() {
 113                 return ManagementFactoryHelper.
 114                            getGarbageCollectorMXBeans();
 115             }
 116         }),
 117 
 118     /**
 119      * Memory manager in the Java virtual machine.
 120      */
 121     MEMORY_MANAGER(
 122         "java.lang.management.MemoryManagerMXBean",
 123         "java.lang", "MemoryManager", keyProperties("name"),
 124         new MXBeanFetcher<MemoryManagerMXBean>() {
 125             public List<MemoryManagerMXBean> getMXBeans() {
 126                 return ManagementFactoryHelper.getMemoryManagerMXBeans();
 127             }
 128         },
 129         GARBAGE_COLLECTOR),
 130 
 131     /**
 132      * Memory pool in the Java virtual machine.
 133      */
 134     MEMORY_POOL(
 135         "java.lang.management.MemoryPoolMXBean",
 136         "java.lang", "MemoryPool", keyProperties("name"),
 137         new MXBeanFetcher<MemoryPoolMXBean>() {
 138             public List<MemoryPoolMXBean> getMXBeans() {
 139                 return ManagementFactoryHelper.getMemoryPoolMXBeans();
 140             }
 141         }),
 142 
 143     /**
 144      * Operating system on which the Java virtual machine is running
 145      */
 146     OPERATING_SYSTEM(
 147         "java.lang.management.OperatingSystemMXBean",
 148         "java.lang", "OperatingSystem", defaultKeyProperties(),
 149         new MXBeanFetcher<OperatingSystemMXBean>() {
 150             public List<OperatingSystemMXBean> getMXBeans() {
 151                 return Collections.singletonList(ManagementFactoryHelper.getOperatingSystemMXBean());
 152             }
 153         }),
 154 
 155     /**
 156      * Runtime system of the Java virtual machine.
 157      */
 158     RUNTIME(
 159         "java.lang.management.RuntimeMXBean",
 160         "java.lang", "Runtime", defaultKeyProperties(),
 161         new MXBeanFetcher<RuntimeMXBean>() {
 162             public List<RuntimeMXBean> getMXBeans() {
 163                 return Collections.singletonList(ManagementFactoryHelper.getRuntimeMXBean());
 164             }
 165         }),
 166 
 167     /**
 168      * Threading system of the Java virtual machine.
 169      */
 170     THREADING(
 171         "java.lang.management.ThreadMXBean",
 172         "java.lang", "Threading", defaultKeyProperties(),
 173         new MXBeanFetcher<ThreadMXBean>() {
 174             public List<ThreadMXBean> getMXBeans() {
 175                 return Collections.singletonList(ManagementFactoryHelper.getThreadMXBean());
 176             }
 177         }),
 178 
 179 
 180     /**
 181      * Logging facility.
 182      */
 183     LOGGING(
 184         "java.util.logging.LoggingMXBean",
 185         "java.util.logging", "Logging", defaultKeyProperties(),
 186         new MXBeanFetcher<LoggingMXBean>() {
 187             public List<LoggingMXBean> getMXBeans() {
 188                 return Collections.singletonList(LogManager.getLoggingMXBean());
 189             }
 190         }),
 191 
 192 
 193     /**
 194      * Buffer pools.
 195      */
 196     BUFFER_POOL(
 197         "java.nio.BufferPoolMXBean",
 198         "java.nio", "BufferPool", keyProperties("name"),
 199         new MXBeanFetcher<BufferPoolMXBean>() {
 200             public List<BufferPoolMXBean> getMXBeans() {
 201                 List<BufferPoolMXBean> pools = new ArrayList<BufferPoolMXBean>(2);
 202                 pools.add( sun.misc.SharedSecrets.getJavaNioAccess().getDirectBufferPoolMXBean() );
 203                 pools.add( sun.nio.ch.FileChannelImpl.getMappedBufferPoolMXBean() );
 204                 return pools;
 205             }
 206         }),
 207 
 208 
 209     // Sun Platform Extension
 210 
 211     /**
 212      * Sun extension garbage collector that performs collections in cycles.
 213      */
 214     SUN_GARBAGE_COLLECTOR(
 215         "com.sun.management.GarbageCollectorMXBean",
 216         "java.lang", "GarbageCollector", keyProperties("name"),
 217         new MXBeanFetcher<com.sun.management.GarbageCollectorMXBean>() {
 218             public List<com.sun.management.GarbageCollectorMXBean> getMXBeans() {
 219                 return getGcMXBeanList(com.sun.management.GarbageCollectorMXBean.class);
 220             }
 221         }),
 222 
 223     /**
 224      * Sun extension operating system on which the Java virtual machine
 225      * is running.
 226      */
 227     SUN_OPERATING_SYSTEM(
 228         "com.sun.management.OperatingSystemMXBean",
 229         "java.lang", "OperatingSystem", defaultKeyProperties(),
 230         new MXBeanFetcher<com.sun.management.OperatingSystemMXBean>() {
 231             public List<com.sun.management.OperatingSystemMXBean> getMXBeans() {
 232                 return getOSMXBeanList(com.sun.management.OperatingSystemMXBean.class);
 233             }
 234         }),
 235 
 236     /**
 237      * Unix operating system.
 238      */
 239     SUN_UNIX_OPERATING_SYSTEM(
 240         "com.sun.management.UnixOperatingSystemMXBean",
 241         "java.lang", "OperatingSystem", defaultKeyProperties(),
 242         new MXBeanFetcher<UnixOperatingSystemMXBean>() {
 243             public List<UnixOperatingSystemMXBean> getMXBeans() {
 244                 return getOSMXBeanList(com.sun.management.UnixOperatingSystemMXBean.class);
 245             }
 246         }),
 247 
 248     /**
 249      * Diagnostic support for the HotSpot Virtual Machine.
 250      */
 251     HOTSPOT_DIAGNOSTIC(
 252         "com.sun.management.HotSpotDiagnosticMXBean",
 253         "com.sun.management", "HotSpotDiagnostic", defaultKeyProperties(),
 254         new MXBeanFetcher<HotSpotDiagnosticMXBean>() {
 255             public List<HotSpotDiagnosticMXBean> getMXBeans() {
 256                 return Collections.singletonList(ManagementFactoryHelper.getDiagnosticMXBean());
 257             }
 258         });
 259 
 260 
 261     /**
 262      * A task that returns the MXBeans for a component.
 263      */
 264     interface MXBeanFetcher<T extends PlatformManagedObject> {
 265         public List<T> getMXBeans();
 266     }
 267 
 268     /*
 269      * Returns a list of the GC MXBeans of the given type.
 270      */
 271     private static <T extends GarbageCollectorMXBean>
 272             List<T> getGcMXBeanList(Class<T> gcMXBeanIntf) {
 273         List<GarbageCollectorMXBean> list =
 274             ManagementFactoryHelper.getGarbageCollectorMXBeans();
 275         List<T> result = new ArrayList<T>(list.size());
 276         for (GarbageCollectorMXBean m : list) {
 277             if (gcMXBeanIntf.isInstance(m)) {
 278                 result.add(gcMXBeanIntf.cast(m));
 279             }
 280         }
 281         return result;
 282     }
 283 
 284     /*
 285      * Returns the OS mxbean instance of the given type.
 286      */
 287     private static <T extends OperatingSystemMXBean>
 288             List<T> getOSMXBeanList(Class<T> osMXBeanIntf) {
 289         OperatingSystemMXBean m =
 290             ManagementFactoryHelper.getOperatingSystemMXBean();
 291         if (osMXBeanIntf.isInstance(m)) {
 292             return Collections.singletonList(osMXBeanIntf.cast(m));
 293         } else {
 294             return Collections.emptyList();
 295         }
 296     }
 297 
 298     private final String mxbeanInterfaceName;
 299     private final String domain;
 300     private final String type;
 301     private final Set<String> keyProperties;
 302     private final MXBeanFetcher fetcher;
 303     private final PlatformComponent[] subComponents;
 304 
 305     private PlatformComponent(String intfName,
 306                               String domain, String type,
 307                               Set<String> keyProperties,
 308                               MXBeanFetcher fetcher) {
 309         this.mxbeanInterfaceName = intfName;
 310         this.domain = domain;
 311         this.type = type;
 312         this.keyProperties = keyProperties;
 313         this.fetcher = fetcher;
 314         this.subComponents = new PlatformComponent[0];
 315     }
 316     private PlatformComponent(String intfName,
 317                               String domain, String type,
 318                               Set<String> keyProperties,
 319                               MXBeanFetcher fetcher,
 320                               PlatformComponent... subComponents) {
 321         this.mxbeanInterfaceName = intfName;
 322         this.domain = domain;
 323         this.type = type;
 324         this.keyProperties = keyProperties;
 325         this.fetcher = fetcher;
 326         this.subComponents = subComponents;
 327     }
 328 
 329     private static Set<String> defaultKeyProps;
 330     private static Set<String> defaultKeyProperties() {
 331         if (defaultKeyProps == null) {
 332             defaultKeyProps = Collections.singleton("type");
 333         }
 334         return defaultKeyProps;
 335     }
 336 
 337     private static Set<String> keyProperties(String... keyNames) {
 338         Set<String> set = new HashSet<String>();
 339         set.add("type");
 340         for (String s : keyNames) {
 341             set.add(s);
 342         }
 343         return set;
 344     }
 345 
 346     String getMXBeanInterfaceName() {
 347         return mxbeanInterfaceName;
 348     }
 349 
 350     @SuppressWarnings("unchecked")
 351     Class<? extends PlatformManagedObject> getMXBeanInterface() {
 352         try {
 353             // Lazy loading the MXBean interface only when it is needed
 354             return (Class<? extends PlatformManagedObject>)
 355                        Class.forName(mxbeanInterfaceName, false, null);
 356         } catch (ClassNotFoundException x) {
 357             throw new AssertionError(x);
 358         }
 359     }
 360 
 361     @SuppressWarnings("unchecked")
 362     <T extends PlatformManagedObject>
 363         List<T> getMXBeans(Class<T> mxbeanInterface)
 364     {
 365         return fetcher.getMXBeans();
 366     }
 367 
 368     <T extends PlatformManagedObject>
 369         List<T> getMXBeans(MBeanServerConnection mbs, Class<T> mxbeanInterface)
 370         throws java.io.IOException
 371     {
 372         List<T> result = new ArrayList<T>();
 373         for (ObjectName on : getObjectNames(mbs)) {
 374             result.add(ManagementFactory.
 375                 newPlatformMXBeanProxy(mbs,
 376                                        on.getCanonicalName(),
 377                                        mxbeanInterface)
 378             );
 379         }
 380         return result;
 381     }
 382 
 383     private Set<ObjectName> getObjectNames(MBeanServerConnection mbs)
 384         throws java.io.IOException
 385     {
 386         String domainAndType = domain + ":type=" + type;
 387         if (keyProperties.size() > 1) {
 388             // if there are more than 1 key properties (i.e. other than "type")
 389             domainAndType += ",*";
 390         }
 391         ObjectName on = ObjectName.valueOf(domainAndType);
 392         Set<ObjectName> set =  mbs.queryNames(on, null);
 393         for (PlatformComponent pc : subComponents) {
 394             set.addAll(pc.getObjectNames(mbs));
 395         }
 396         return set;
 397     }
 398 
 399     private static final long serialVersionUID = 6992337162326171013L;
 400 }