1 /* 2 * Copyright (c) 2015, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.management.spi; 27 28 import java.util.Collections; 29 import java.util.List; 30 import java.util.Map; 31 import java.util.ServiceLoader; 32 import java.util.Set; 33 import java.util.stream.Collectors; 34 35 /** 36 * The PlatformMBeanProvider class defines the abstract service interface 37 * that the {@link java.lang.management.ManagementFactory} will invoke to find, 38 * load, and register Platform MBeans. 39 * 40 * ManagementFactory loads the {@linkplain ServiceLoader#loadInstalled(java.lang.Class) 41 * installed providers} of this service interface and each provides the 42 * {@linkplain PlatformComponent platform components} that defines MXBean 43 * or DynamicMBean to be registered in the platform MBeanServer. 44 * 45 * A {@code PlatformMBeanProvider} will implement the {@code getPlatformComponentList()} 46 * method to return the list of {@code PlatformComponents} it provides. 47 */ 48 public abstract class PlatformMBeanProvider { 49 /** 50 * {@code PlatformComponent} models MBeans of a management interface supported 51 * by the platform. 52 * 53 * If a PlatformComponent models a singleton MBean, the {@link #getObjectNamePattern() 54 * ObjectName pattern} must be the {@link 55 * javax.management.ObjectName#getCanonicalName() canonical name} of that 56 * singleton MBean. Otherwise, it must be an ObjectName pattern 57 * that can be used to query the MBeans for this 58 * PlatformComponent registered in a {@code MBeanServer}. 59 * <br> 60 * The {@link #getObjectNamePattern() ObjectName pattern} serves as a unique 61 * key for identifying the instance of PlatformComponent. It is thus illegal 62 * for a given {@link PlatformMBeanProvider} to export several instance of 63 * PlatformComponent with the same 64 * {@link #getObjectNamePattern() ObjectName pattern} string. 65 * <br> 66 * If two different provider instances export a PlatformComponent for the 67 * same ObjectName pattern, only the PlatformComponent instance of the first 68 * provider will be taken into account. 69 * 70 * @param <T> The higher level interface for which the MBeans modeled by 71 * this object should be recognized. For instance, for the {@link 72 * java.lang.management.ManagementFactory#getOperatingSystemMXBean() 73 * Operating System MXBean}, this should be {@link 74 * java.lang.management.OperatingSystemMXBean 75 * java.lang.management.OperatingSystemMXBean}. 76 */ 77 public interface PlatformComponent<T> { 78 /** 79 * Returns the names of the management interfaces implemented by the 80 * MBeans modeled by this {@code PlatformComponent}. 81 * 82 * @implNote 83 * When {@link java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class) 84 * ManagementFactory.getPlatformMXBean(mxbeanInterface)} or {@link 85 * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class) 86 * ManagementFactory.getPlatformMXBeans(mxbeanInterface)} are invoked, 87 * this PlatformComponent instance will match only if the name of the 88 * given {@code mxbeanInterface} is found in this list. 89 * 90 * @return the names of the management interfaces exported by the MBeans 91 * modeled by this object. 92 */ 93 public Set<String> mbeanInterfaceNames(); 94 95 /** 96 * A map from ObjectName string to the MBean instance this 97 * {@code PlatformComponent} creates. 98 * 99 * @implNote 100 * If {@link #shouldRegister()} is {@code true}, this method 101 * will be called when the {@link java.lang.management.ManagementFactory 102 * #getPlatformMBeanServer() Platform MBeanServer} is initialized. 103 * By default, this method will also be called by {@link 104 * #getMBeans(java.lang.Class)}, when {@link 105 * java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class) 106 * ManagementFactory.getPlatformMXBean(mxbeanInterface)} or {@link 107 * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class) 108 * ManagementFactory.getPlatformMXBeans(mxbeanInterface)} are invoked, 109 * and when the name of the given {@code mxbeanInterface} is contained 110 * in the names of management interfaces returned by {@link 111 * #mbeanInterfaceNames()}. 112 * 113 * @return A map with, for each MBean, the ObjectName string as key 114 * and the MBean as value. 115 */ 116 public Map<String, T> nameToMBeanMap(); 117 118 /** 119 * An ObjectName pattern uniquely identifies the MBeans 120 * modeled by this {@code PlatformComponent}. 121 * If this instance models a singleton MBean, this must be 122 * the {@link 123 * javax.management.ObjectName#getCanonicalName() canonical name} 124 * of that singleton MBean. 125 * 126 * @return An ObjectName pattern uniquely identifies the MBeans 127 * modeled by this instance. 128 */ 129 public String getObjectNamePattern(); 130 131 /** 132 * Returns {@code true} if this {@code PlatformComponent} models 133 * a singleton MBean. By default, {@code true} is assumed. 134 * 135 * @return {@code true} if this instance models a singleton MBean. 136 */ 137 public default boolean isSingleton() { 138 return true; 139 } 140 141 /** 142 * Returns {@code true} if the MBeans modeled by this {@code PlatformComponent} 143 * should automatically be registered in the {@link 144 * java.lang.management.ManagementFactory#getPlatformMBeanServer() 145 * Platform MBeanServer}. By default, {@code true} is assumed. 146 * 147 * @return {@code true} if the MBeans modeled by this instance should 148 * automatically be registered in the Platform MBeanServer. 149 */ 150 public default boolean shouldRegister() { 151 return true; 152 } 153 154 /** 155 * The set of interfaces implemented by the MBeans modeled 156 * by this {@code PlatformComponent}. 157 * 158 * @implNote 159 * {@link java.lang.management.ManagementFactory#getPlatformManagementInterfaces() 160 * ManagementFactory.getPlatformManagementInterfaces()} calls this 161 * method to find the management interfaces supported by the platform. 162 * 163 * @return The set of interfaces implemented by the MBeans modeled 164 * by this instance 165 */ 166 public Set<Class<? extends T>> mbeanInterfaces(); 167 168 /** 169 * Return the list of MBeans that implement the given {@code mbeanIntf} 170 * modeled by this {@code PlatformComponent}. This method returns an 171 * empty list if no MBean implements the given {@code mbeanIntf}. 172 * 173 * @implNote This method will be called when {@link 174 * java.lang.management.ManagementFactory#getPlatformMXBean(java.lang.Class) 175 * ManagementFactory.getPlatformMXBean(mbeanIntf)} or {@link 176 * java.lang.management.ManagementFactory#getPlatformMXBeans(java.lang.Class) 177 * ManagementFactory.getPlatformMXBeans(mbeanIntf)} are invoked. 178 * By default it first checks whether the specified {@code mbeanIntf} 179 * name is contained in the returned list from the {@link #mbeanInterfaceNames()} 180 * method. If yes, it proceeds and calls 181 * {@link #mbeans().values()} and filters out all 182 * MBeans which are not instances of the given {@code mbeanIntf}. 183 * Otherwise, it returns an empty list. 184 * 185 * @param mbeanIntf A management interface. 186 * @return A (possibly empty) list of MBeans implementing the given 187 * {@code mbeanIntf}. 188 */ 189 public default <I> List<? extends I> getMBeans(Class<I> mbeanIntf) { 190 List<I> list; 191 192 if (!mbeanInterfaceNames().contains(mbeanIntf.getName())) { 193 list = Collections.emptyList(); 194 } else { 195 list = nameToMBeanMap().values().stream() 196 .filter(mbeanIntf::isInstance) 197 .map(mbeanIntf::cast) 198 .collect(Collectors.toList()); 199 } 200 return list; 201 } 202 } 203 204 /** 205 * Instantiates a new PlatformMBeanProvider. 206 * 207 * @throws SecurityException if the subclass (and calling code) does not 208 * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider.subclass")} 209 */ 210 protected PlatformMBeanProvider () { 211 this(checkSubclassPermission()); 212 } 213 214 private PlatformMBeanProvider(Void unused) { 215 } 216 217 /** 218 * Returns a list of PlatformComponent instances describing the Platform 219 * MBeans provided by this provider. 220 * 221 * @return a list of PlatformComponent instances describing the Platform 222 * MBeans provided by this provider. 223 */ 224 public abstract List<PlatformComponent<?>> getPlatformComponentList(); 225 226 private static Void checkSubclassPermission() { 227 SecurityManager sm = System.getSecurityManager(); 228 if (sm != null) { 229 sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName()+".subclass")); 230 } 231 return null; 232 } 233 }