1 /* 2 * Copyright (c) 2016, 2019, 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 jdk.management.jfr; 27 28 import java.util.ArrayList; 29 import java.util.Collections; 30 import java.util.List; 31 import java.util.StringJoiner; 32 33 import javax.management.openmbean.CompositeData; 34 35 import jdk.jfr.Category; 36 import jdk.jfr.EventType; 37 import jdk.jfr.SettingDescriptor; 38 39 /** 40 * Management representation of an {@code EventType}. 41 * 42 * @see EventType 43 * 44 * @since 9 45 */ 46 public final class EventTypeInfo { 47 private final List<SettingDescriptorInfo> settings; 48 private final long id; 49 private final String name; 50 private final String description; 51 private final String label; 52 private final List<String> categoryNames; 53 54 // package private 55 EventTypeInfo(EventType eventType) { 56 this.settings = creatingSettingDescriptorInfos(eventType); 57 this.id = eventType.getId(); 58 this.name = eventType.getName(); 59 this.label = eventType.getLabel(); 60 this.description = eventType.getDescription(); 61 this.categoryNames = eventType.getCategoryNames(); 62 } 63 64 private EventTypeInfo(CompositeData cd) { 65 this.settings = createSettings(cd.get("settings")); 66 this.id = (long) cd.get("id"); 67 this.name = (String) cd.get("name"); 68 this.label = (String) cd.get("label"); 69 this.description = (String) cd.get("description"); 70 this.categoryNames = createCategoryNames((Object[]) cd.get("category")); 71 } 72 73 private static List<String> createCategoryNames(Object[] array) { 74 List<String> list = new ArrayList<>(array.length); 75 for (int i = 0; i < array.length; i++) { 76 list.add((String) array[i]); 77 } 78 return Collections.unmodifiableList(list); 79 } 80 81 private static List<SettingDescriptorInfo> creatingSettingDescriptorInfos(EventType eventType) { 82 List<SettingDescriptor> settings = eventType.getSettingDescriptors(); 83 List<SettingDescriptorInfo> settingDescriptorInfos = new ArrayList<>(settings.size()); 84 for (SettingDescriptor s : settings) { 85 settingDescriptorInfos.add(new SettingDescriptorInfo(s)); 86 } 87 return Collections.unmodifiableList(settingDescriptorInfos); 88 } 89 90 private static List<SettingDescriptorInfo> createSettings(Object settings) { 91 if (settings != null && settings.getClass().isArray()) { 92 Object[] settingsArray = (Object[]) settings; 93 List<SettingDescriptorInfo> list = new ArrayList<>(settingsArray.length); 94 for (Object cd : settingsArray) { 95 if (cd instanceof CompositeData) { 96 list.add(SettingDescriptorInfo.from((CompositeData) cd)); 97 } 98 } 99 return Collections.unmodifiableList(list); 100 } 101 return Collections.emptyList(); 102 } 103 104 /** 105 * Returns the label, a human-readable name, associated with the event type 106 * for this {@link EventTypeInfo}, for example {@code "Garbage Collection"}. 107 * 108 * @return the label 109 * 110 * @see EventType#getLabel() 111 */ 112 public String getLabel() { 113 return label; 114 } 115 116 /** 117 * 118 * Returns the list of human-readable names that makes up the category for 119 * this event type, for instance "Java Virtual Machine", 120 * "Garbage Collector". 121 * 122 * @return an immutable list of category names, or a list with the name 123 * "Uncategorized" if no category has been set 124 * 125 * @see EventType#getCategoryNames() 126 * @see Category 127 */ 128 public List<String> getCategoryNames() { 129 return categoryNames; 130 } 131 132 /** 133 * Returns the unique numeric id for the event type associated with this 134 * {@link EventTypeInfo}, not guaranteed to be the same for different JVM 135 * instances. 136 * 137 * @return the id 138 * 139 * @see EventType#getId() 140 */ 141 public long getId() { 142 return id; 143 } 144 145 /** 146 * Returns the name for the event type associated with this 147 * {@link EventTypeInfo}, for example 148 * {@code "com.oracle.jdk.GarbageCollection"}. 149 * 150 * @return the name 151 * 152 * @see EventType#getName() 153 */ 154 public String getName() { 155 return name; 156 } 157 158 /** 159 * Returns a short sentence or two describing the event type associated with 160 * this {@code EventTypeInfo}, for example 161 * {@code ""Garbage collection performed by the JVM""}. 162 * 163 * @return the description, or {@code null} if no description exists 164 * 165 * @see EventType#getDescription() 166 */ 167 public String getDescription() { 168 return description; 169 } 170 171 /** 172 * Returns settings for the event type associated with this 173 * {@code EventTypeInfo}. 174 * 175 * @return the settings, not {@code null} 176 * 177 * @see EventType#getSettingDescriptors() 178 */ 179 public List<SettingDescriptorInfo> getSettingDescriptors() { 180 return settings; 181 } 182 183 /** 184 * Returns a string description of this {@link EventTypeInfo}. 185 * 186 * @return description, not {@code null} 187 */ 188 @Override 189 public String toString() { 190 Stringifier s = new Stringifier(); 191 s.add("id", id); 192 s.add("name", name); 193 s.add("label", label); 194 s.add("description", description); 195 StringJoiner sj = new StringJoiner(", ", "{", "}"); 196 for (String categoryName : categoryNames) { 197 sj.add(categoryName); 198 } 199 s.add("category", sj.toString()); 200 return s.toString(); 201 } 202 203 /** 204 * Returns an {@code EventType} represented by the specified 205 * {@code CompositeData} 206 * <p> 207 * The supplied {@code CompositeData} must have the following item names and 208 * item types to be valid. <blockquote> 209 * <table class="striped"> 210 * <caption>The name and type the specified CompositeData must contain</caption> 211 * <thead> 212 * <tr> 213 * <th scope="col" style="text-align:left">Name</th> 214 * <th scope="col" style="text-align:left">Type</th> 215 * </tr> 216 * </thead> 217 * <tbody> 218 * <tr> 219 * <th scope="row">id</th> 220 * <td>{@code Long}</td> 221 * </tr> 222 * <tr> 223 * <th scope="row">name</th> 224 * <td>{@code String}</td> 225 * </tr> 226 * <tr> 227 * <th scope="row">label</th> 228 * <td>{@code String}</td> 229 * </tr> 230 * <tr> 231 * <th scope="row">description</th> 232 * <td>{@code String}</td> 233 * </tr> 234 * <tr> 235 * <th scope="row">category</th> 236 * <td><code>ArrayType(1, SimpleType.STRING)</code></td> 237 * </tr> 238 * <tr> 239 * <th scope="row">settings</th> 240 * <td>{@code javax.management.openmbean.CompositeData[]} whose element type 241 * is the mapped type for {@link SettingDescriptorInfo} as specified in the 242 * {@link SettingDescriptorInfo#from} method.</td> 243 * 244 * </tr> 245 * </tbody> 246 * </table> 247 * </blockquote> 248 * 249 * @param cd {@code CompositeData} representing the {@code EventTypeInfo} to 250 * return 251 * 252 * @throws IllegalArgumentException if {@code cd} does not represent a valid 253 * {@code EventTypeInfo} 254 * 255 * @return an {@code EventTypeInfo}, or {@code null} if {@code cd} is 256 * {@code null} 257 */ 258 public static EventTypeInfo from(CompositeData cd) { 259 if (cd == null) { 260 return null; 261 } 262 return new EventTypeInfo(cd); 263 } 264 }