/* |
|
* 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 8 |
|
*/ |
|
public final class EventType { |
|
private final PlatformEventType platformEventType; |
|
private final List<String> UNCATEGORIZED = Collections.singletonList("Uncategorized"); |
|
private Map<String, ValueDescriptor> 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<ValueDescriptor> 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 <code>null</code> if |
|
* the field with the specified name doesn't exist |
|
* |
|
* @return a value descriptor, or <code>null</code> if it doesn't exist |
|
*/ |
|
public ValueDescriptor getField(String name) { |
|
Objects.requireNonNull(name); |
|
if (cache == null) { |
|
List<ValueDescriptor> fields = getFields(); |
|
Map<String, ValueDescriptor> newCache = new LinkedHashMap<String, ValueDescriptor>(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.CPULoad"}). |
|
* <p> |
|
* 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"}). |
|
* <p> |
|
* The label of an event class can be set with {@link Label}. |
|
* |
|
* @return the label, or {@code null} if a label is not 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<AnnotationElement> getAnnotationElements() { |
|
return platformEventType.getAnnotationElements(); |
|
} |
|
/** |
|
* Returns {@code true} if the event is enabled and at least one recording is |
|
* running, {@code false} otherwise. |
|
* <p> |
|
* 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. |
|
* <p> |
|
* 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 <A> 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 extends Annotation> A getAnnotation(Class<A> 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<? extends Event> 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<SettingDescriptor> getSettingDescriptors() { |
|
return Collections.unmodifiableList(platformEventType.getSettings()); |
|
} |
|
/** |
|
* Returns the list of human-readable names that makes up the categories for |
|
* this event type (for example, {@code "Java Application"}, {@code "Statistics"}). |
|
* |
|
* @return an immutable list of category names, or a list with the name |
|
* {@code "Uncategorized"} if no category is set |
|
* |
|
* @see Category |
|
*/ |
|
public List<String> 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; |
|
} |
|
} |