blob: e67489becc3fbc01af4e3de3a8c27a1bf991f4ed [file] [log] [blame]
/*
* Copyright (c) 2016, 2018, 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<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;
}
}