--- /dev/null 2018-06-17 23:18:20.806999507 +0800 +++ new/src/share/classes/jdk/jfr/EventType.java 2019-01-29 10:58:38.738341484 +0800 @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr; + +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import jdk.jfr.internal.JVMSupport; +import jdk.jfr.internal.MetadataRepository; +import jdk.jfr.internal.PlatformEventType; +import jdk.jfr.internal.Type; +import jdk.jfr.internal.Utils; + +/** + * Describes an event, its fields, settings and annotations. + * + * @since 9 + */ +public final class EventType { + private final PlatformEventType platformEventType; + private final List UNCATEGORIZED = Collections.singletonList("Uncategorized"); + private Map cache; // create lazy to avoid memory overhead + // helper constructor + EventType(PlatformEventType platformEventType) { + this.platformEventType = platformEventType; + } + + /** + * Returns an immutable list of descriptors that describe the event fields of + * this event type. + * + * @return the list of field descriptors, not {@code null} + */ + public List getFields() { + return platformEventType.getFields(); + } + + /** + * Returns the field with the specified name, or {@code null} if it doesn't + * exist. + * + * @return a value descriptor that describes the field, or null if + * the field with the specified name doesn't exist + * + * @return a value descriptor, or null if it doesn't exist + */ + public ValueDescriptor getField(String name) { + Objects.requireNonNull(name); + if (cache == null) { + List fields = getFields(); + Map newCache = new LinkedHashMap(fields.size()); + for (ValueDescriptor v :fields) { + newCache.put(v.getName(), v); + } + cache = newCache; + } + return cache.get(name); + } + + /** + * Returns an identifier for the event (for example, + * {@code "jdk.jfr.CPULoad"}). + *

+ * The identifier is the fully qualified name of the event class, if not set using + * the {@link Name} annotation. + * + * @return the name, not {@code null} + * + * @see Name + */ + public String getName() { + return platformEventType.getName(); + } + + /** + * Returns a human-readable name (for example, {@code "CPU Load"}). + *

+ * The label of an event class can be set with {@link Label}. + * + * @return the label, or {@code null} if a label is not been set + * + * @see Label + */ + public String getLabel() { + return platformEventType.getLabel(); + } + + /** + * Returns a unique ID for this event type in the Java Virtual Machine (JVM). + * + * @return the ID that is used in the JVM + */ + public long getId() { + return platformEventType.getId(); + } + + /** + * Returns an immutable list of annotation elements for this event type. + * + * @return an immutable list of annotations or an empty list if no + * annotations exists, not {@code null} + */ + public List getAnnotationElements() { + return platformEventType.getAnnotationElements(); + } + + /** + * Returns {@code true} if the event is enabled and at least one recording is + * running, {@code false} otherwise. + *

+ * By default, the event is enabled. The event can be enabled or disabled by + * setting the enabled setting to {@code true} or {@code false}, programmatically or by using a + * configuration file. The event can also be disabled by annotating event with + * the {@code @Enabled(false)} annotation. + * + * @return true if event is enabled, false otherwise + * + * @see Enabled + * @see Recording#enable(Class) + */ + public boolean isEnabled() { + return platformEventType.isEnabled(); + } + + /** + * Returns a short sentence that describes the event class. + *

+ * The description of an event class can be set with {@link Description}. + * + * @return the description, or {@code null} if no description exists + * + * @see Description + */ + public String getDescription() { + return platformEventType.getDescription(); + } + + /** + * Returns the first annotation for the specified type if an annotation + * element with the same name is directly present, otherwise {@code null}. + * + * @param the type of the annotation to query for and return if present + * @param annotationClass the {@code Class} object that corresponds to the + * annotation type, not {@code null} + * @return this element's annotation for the specified annotation type if + * directly present, else {@code null} + */ + public A getAnnotation(Class annotationClass) { + Objects.requireNonNull(annotationClass); + return platformEventType.getAnnotation(annotationClass); + } + + /** + * Returns the event type for an event class, or {@code null} if it doesn't + * exist. + * + * @param eventClass the event class, not {@code null} + * @return the event class, or null if class doesn't exist + * + * @throws IllegalArgumentException if {@code eventClass} is an abstract class + * + * @throws IllegalStateException if the class is annotated with + * {@code Registered(false)}, but not manually registered + */ + public static EventType getEventType(Class eventClass) { + Objects.requireNonNull(eventClass); + Utils.ensureValidEventSubclass(eventClass); + JVMSupport.ensureWithInternalError(); + return MetadataRepository.getInstance().getEventType(eventClass); + } + + /** + * Returns an immutable list of the setting descriptors that describe the available + * event settings for this event type. + * + * @return the list of setting descriptors for this event type, not + * {@code null} + */ + public List getSettingDescriptors() { + return Collections.unmodifiableList(platformEventType.getSettings()); + } + + /** + * Returns the list of human-readable names that makes up the categories for + * this event type (for example, "Java Application", "Statistics"). + * + * @return an immutable list of category names, or a list with the name + * "Uncategorized" if no category is set + * + * @see Category + */ + public List getCategoryNames() { + Category c = platformEventType.getAnnotation(Category.class); + if (c == null) { + return UNCATEGORIZED; + } + return Collections.unmodifiableList(Arrays.asList(c.value())); + } + + // package private + Type getType() { + return platformEventType; + } + + // package private + PlatformEventType getPlatformEventType() { + return platformEventType; + } +}