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 */
25package java.lang.management;
26
27import java.util.ArrayList;
28import java.util.Collections;
29import java.util.HashMap;
30import java.util.List;
31import java.util.Map;
32import java.util.Set;
33import java.util.function.Function;
34import java.util.stream.Collectors;
35import java.util.stream.Stream;
36import javax.management.ObjectName;
37import sun.management.ManagementFactoryHelper;
38import sun.management.spi.PlatformMBeanProvider;
39
40class DefaultPlatformMBeanProvider extends PlatformMBeanProvider {
41    private final List<PlatformComponent<?>> mxbeanList;
42
43    DefaultPlatformMBeanProvider() {
44        mxbeanList = Collections.unmodifiableList(init());
45    }
46
47    @Override
48    public List<PlatformComponent<?>> getPlatformComponentList() {
49        return mxbeanList;
50    }
51
52    private List<PlatformComponent<?>> init() {
53        ArrayList<PlatformComponent<?>> initMBeanList = new ArrayList<>();
54        /**
55         * Class loading system of the Java virtual machine.
56         */
57        initMBeanList.add(new PlatformComponent<ClassLoadingMXBean>() {
58            private final Set<String> classLoadingInterfaceNames =
59                    Collections.unmodifiableSet(Collections.singleton(
60                            "java.lang.management.ClassLoadingMXBean"));
61
62            @Override
63            public Set<Class<? extends ClassLoadingMXBean>> mbeanInterfaces() {
64                return Collections.singleton(ClassLoadingMXBean.class);
65            }
66
67            @Override
68            public Set<String> mbeanInterfaceNames() {
69                return classLoadingInterfaceNames;
70            }
71
72            @Override
73            public String getObjectNamePattern() {
74                return ManagementFactory.CLASS_LOADING_MXBEAN_NAME;
75            }
76
77            @Override
78            public Map<String, ClassLoadingMXBean> nameToMBeanMap() {
79                return Collections.singletonMap(
80                        ManagementFactory.CLASS_LOADING_MXBEAN_NAME,
81                        ManagementFactoryHelper.getClassLoadingMXBean());
82            }
83        });
84
85        /**
86         * Compilation system of the Java virtual machine.
87         */
88        initMBeanList.add(new PlatformComponent<CompilationMXBean>() {
89            private final Set<String> compilationMXBeanInterfaceNames
90                    = Collections.unmodifiableSet(Collections.singleton(
91                            "java.lang.management.CompilationMXBean"));
92
93            @Override
94            public Set<Class<? extends CompilationMXBean>> mbeanInterfaces() {
95                return Collections.singleton(CompilationMXBean.class);
96            }
97
98            @Override
99            public Set<String> mbeanInterfaceNames() {
100                return compilationMXBeanInterfaceNames;
101            }
102
103            @Override
104            public String getObjectNamePattern() {
105                return ManagementFactory.COMPILATION_MXBEAN_NAME;
106            }
107
108            @Override
109            public Map<String, CompilationMXBean> nameToMBeanMap() {
110                CompilationMXBean m = ManagementFactoryHelper.getCompilationMXBean();
111                if (m == null) {
112                    return Collections.emptyMap();
113                } else {
114                    return Collections.singletonMap(
115                            ManagementFactory.COMPILATION_MXBEAN_NAME,
116                            ManagementFactoryHelper.getCompilationMXBean());
117                }
118            }
119        });
120
121        /**
122         * Memory system of the Java virtual machine.
123         */
124        initMBeanList.add(new PlatformComponent<MemoryMXBean>() {
125            private final Set<String> memoryMXBeanInterfaceNames
126                    = Collections.unmodifiableSet(Collections.singleton(
127                            "java.lang.management.MemoryMXBean"));
128
129            @Override
130            public Set<Class<? extends MemoryMXBean>> mbeanInterfaces() {
131                return Collections.singleton(MemoryMXBean.class);
132            }
133
134            @Override
135            public Set<String> mbeanInterfaceNames() {
136                return memoryMXBeanInterfaceNames;
137            }
138
139            @Override
140            public String getObjectNamePattern() {
141                return ManagementFactory.MEMORY_MXBEAN_NAME;
142            }
143
144            @Override
145            public Map<String, MemoryMXBean> nameToMBeanMap() {
146                return Collections.singletonMap(
147                        ManagementFactory.MEMORY_MXBEAN_NAME,
148                        ManagementFactoryHelper.getMemoryMXBean());
149            }
150        });
151
152        /**
153         * Garbage Collector in the Java virtual machine.
154         */
155        initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
156            private final Set<String> garbageCollectorMXBeanInterfaceNames
157                    = Collections.unmodifiableSet(
158                            Stream.of("java.lang.management.MemoryManagerMXBean",
159                                    "java.lang.management.GarbageCollectorMXBean")
160                            .collect(Collectors.toSet()));
161            @Override
162            public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
163                return Stream.of(MemoryManagerMXBean.class,
164                        GarbageCollectorMXBean.class).collect(Collectors.toSet());
165            }
166
167            @Override
168            public Set<String> mbeanInterfaceNames() {
169                return garbageCollectorMXBeanInterfaceNames;
170            }
171
172            @Override
173            public String getObjectNamePattern() {
174                return ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=*";
175            }
176
177            @Override
178            public boolean isSingleton() {
179                return false; // zero or more instances
180            }
181
182            @Override
183            public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
184                List<GarbageCollectorMXBean> list
185                        = ManagementFactoryHelper.getGarbageCollectorMXBeans();
186                Map<String, MemoryManagerMXBean> map;
187                if (list.isEmpty()) {
188                    map = Collections.emptyMap();
189                } else {
190                    map = new HashMap<>(list.size());
191                    for (MemoryManagerMXBean gcm : list) {
192                        map.put(gcm.getObjectName().getCanonicalName(),
193                                gcm);
194                    }
195                }
196                return map;
197            }
198
199        });
200
201        /**
202         * Memory manager in the Java virtual machine.
203         */
204        initMBeanList.add(new PlatformComponent<MemoryManagerMXBean>() {
205            private final Set<String> memoryManagerMXBeanInterfaceNames
206                    = Collections.unmodifiableSet(Collections.singleton(
207                            "java.lang.management.MemoryManagerMXBean"));
208
209            @Override
210            public Set<Class<? extends MemoryManagerMXBean>> mbeanInterfaces() {
211                return Collections.singleton(MemoryManagerMXBean.class);
212            }
213
214            @Override
215            public Set<String> mbeanInterfaceNames() {
216                return memoryManagerMXBeanInterfaceNames;
217            }
218
219            @Override
220            public String getObjectNamePattern() {
221                return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE + ",name=*";
222            }
223
224            @Override
225            public boolean isSingleton() {
226                return false; // zero or more instances
227            }
228
229            @Override
230            public Map<String, MemoryManagerMXBean> nameToMBeanMap() {
231                List<MemoryManagerMXBean> list
232                        = ManagementFactoryHelper.getMemoryManagerMXBeans();
233                return list.stream()
234                        .filter(this::isMemoryManager)
235                        .collect(Collectors.toMap(
236                                pmo -> pmo.getObjectName().getCanonicalName(), Function.identity()));
237            }
238
239            // ManagementFactoryHelper.getMemoryManagerMXBeans() returns all
240            // memory managers - we need to filter out those that do not match
241            // the pattern for which we are registered
242            private boolean isMemoryManager(MemoryManagerMXBean mbean) {
243                final ObjectName name = mbean.getObjectName();
244                return ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.startsWith(name.getDomain())
245                        && ManagementFactory.MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE.contains(
246                                "type="+name.getKeyProperty("type"));
247            }
248        });
249
250        /**
251         * Memory pool in the Java virtual machine.
252         */
253        initMBeanList.add(new PlatformComponent<MemoryPoolMXBean>() {
254            private final Set<String> memoryPoolMXBeanInterfaceNames
255                    = Collections.unmodifiableSet(Collections.singleton(
256                            "java.lang.management.MemoryPoolMXBean"));
257
258            @Override
259            public Set<Class<? extends MemoryPoolMXBean>> mbeanInterfaces() {
260                return Collections.singleton(MemoryPoolMXBean.class);
261            }
262
263            @Override
264            public Set<String> mbeanInterfaceNames() {
265                return memoryPoolMXBeanInterfaceNames;
266            }
267
268            @Override
269            public String getObjectNamePattern() {
270                return ManagementFactory.MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=*";
271            }
272
273            @Override
274            public boolean isSingleton() {
275                return false; // zero or more instances
276            }
277
278            @Override
279            public Map<String, MemoryPoolMXBean> nameToMBeanMap() {
280                List<MemoryPoolMXBean> list
281                        = ManagementFactoryHelper.getMemoryPoolMXBeans();
282                Map<String, MemoryPoolMXBean> map;
283                if (list.isEmpty()) {
284                    map = Collections.<String, MemoryPoolMXBean>emptyMap();
285                } else {
286                    map = new HashMap<>(list.size());
287                    for (MemoryPoolMXBean mpm : list) {
288                        map.put(mpm.getObjectName().getCanonicalName(),
289                                mpm);
290                    }
291                }
292                return map;
293            }
294        });
295
296        /**
297         * Runtime system of the Java virtual machine.
298         */
299        initMBeanList.add(new PlatformComponent<RuntimeMXBean>() {
300            private final Set<String> runtimeMXBeanInterfaceNames
301                    = Collections.unmodifiableSet(Collections.singleton(
302                            "java.lang.management.RuntimeMXBean"));
303
304            @Override
305            public Set<Class<? extends RuntimeMXBean>> mbeanInterfaces() {
306                return Collections.singleton(RuntimeMXBean.class);
307            }
308
309            @Override
310            public Set<String> mbeanInterfaceNames() {
311                return runtimeMXBeanInterfaceNames;
312            }
313
314            @Override
315            public String getObjectNamePattern() {
316                return ManagementFactory.RUNTIME_MXBEAN_NAME;
317            }
318
319            @Override
320            public Map<String, RuntimeMXBean> nameToMBeanMap() {
321                return Collections.singletonMap(
322                        ManagementFactory.RUNTIME_MXBEAN_NAME,
323                        ManagementFactoryHelper.getRuntimeMXBean());
324            }
325        });
326
327        /**
328         * Threading system of the Java virtual machine.
329         */
330        initMBeanList.add(new PlatformComponent<ThreadMXBean>() {
331            private final Set<String> threadMXBeanInterfaceNames
332                    = Collections.unmodifiableSet(Collections.singleton(
333                            "java.lang.management.ThreadMXBean"));
334
335            @Override
336            public Set<Class<? extends ThreadMXBean>> mbeanInterfaces() {
337                return Collections.singleton(ThreadMXBean.class);
338            }
339
340            @Override
341            public Set<String> mbeanInterfaceNames() {
342                return threadMXBeanInterfaceNames;
343            }
344
345            @Override
346            public String getObjectNamePattern() {
347                return ManagementFactory.THREAD_MXBEAN_NAME;
348            }
349
350            @Override
351            public Map<String, ThreadMXBean> nameToMBeanMap() {
352                return Collections.singletonMap(
353                        ManagementFactory.THREAD_MXBEAN_NAME,
354                        ManagementFactoryHelper.getThreadMXBean());
355            }
356        });
357
358        if (ManagementFactoryHelper.isPlatformLoggingMXBeanAvailable()) {
359            /**
360             * Logging facility.
361             */
362            initMBeanList.add(new PlatformComponent<PlatformLoggingMXBean>() {
363                private final Set<String> platformLoggingMXBeanInterfaceNames
364                    = Collections.unmodifiableSet(Collections.singleton(
365                            "java.lang.management.PlatformLoggingMXBean"));
366
367                @Override
368                public Set<Class<? extends PlatformLoggingMXBean>> mbeanInterfaces() {
369                    return Collections.singleton(PlatformLoggingMXBean.class);
370                }
371
372                @Override
373                public Set<String> mbeanInterfaceNames() {
374                    return platformLoggingMXBeanInterfaceNames;
375                }
376
377                @Override
378                public String getObjectNamePattern() {
379                    return "java.util.logging:type=Logging";
380                }
381
382                @Override
383                public Map<String, PlatformLoggingMXBean> nameToMBeanMap() {
384                    return Collections.singletonMap(
385                        "java.util.logging:type=Logging",
386                        ManagementFactoryHelper.getPlatformLoggingMXBean());
387                }
388            });
389        }
390
391        /**
392         * Buffer pools.
393         */
394        initMBeanList.add(new PlatformComponent<BufferPoolMXBean>() {
395            private final Set<String> bufferPoolMXBeanInterfaceNames
396                    = Collections.unmodifiableSet(Collections.singleton(
397                            "java.lang.management.BufferPoolMXBean"));
398
399            @Override
400            public Set<Class<? extends BufferPoolMXBean>> mbeanInterfaces() {
401                return Collections.singleton(BufferPoolMXBean.class);
402            }
403
404            @Override
405            public Set<String> mbeanInterfaceNames() {
406                return bufferPoolMXBeanInterfaceNames;
407            }
408
409            @Override
410            public String getObjectNamePattern() {
411                return "java.nio:type=BufferPool,name=*";
412            }
413
414            @Override
415            public boolean isSingleton() {
416                return false; // zero or more instances
417            }
418
419            @Override
420            public Map<String, BufferPoolMXBean> nameToMBeanMap() {
421                List<BufferPoolMXBean> list
422                        = ManagementFactoryHelper.getBufferPoolMXBeans();
423                Map<String, BufferPoolMXBean> map;
424                if (list.isEmpty()) {
425                    map = Collections.<String, BufferPoolMXBean>emptyMap();
426                } else {
427                    map = new HashMap<>(list.size());
428                    list.stream()
429                        .forEach(mbean -> map.put(mbean.getObjectName().getCanonicalName(),mbean));
430                }
431                return map;
432            }
433        });
434
435        /**
436         * OperatingSystemMXBean
437         */
438        initMBeanList.add(new PlatformComponent<OperatingSystemMXBean>() {
439            private final Set<String> operatingSystemMXBeanInterfaceNames
440                    = Collections.unmodifiableSet(Collections.singleton(
441                            "java.lang.management.OperatingSystemMXBean"));
442
443            @Override
444            public Set<Class<? extends OperatingSystemMXBean>> mbeanInterfaces() {
445                return Collections.singleton(OperatingSystemMXBean.class);
446            }
447
448            @Override
449            public Set<String> mbeanInterfaceNames() {
450                return operatingSystemMXBeanInterfaceNames;
451            }
452
453            @Override
454            public String getObjectNamePattern() {
455                return ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME;
456            }
457
458            @Override
459            public Map<String, OperatingSystemMXBean> nameToMBeanMap() {
460                return Collections.singletonMap(
461                        ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME,
462                        ManagementFactoryHelper.getOperatingSystemMXBean());
463            }
464
465        });
466
467        initMBeanList.trimToSize();
468        return initMBeanList;
469    }
470}
471