Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/src/jdk.jfr/share/classes/jdk/jfr/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 9 kB image not shown  

Quelle  EventFactory.java   Sprache: JAVA

 
/*
 * Copyright (c) 2016, 2022, 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.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import jdk.internal.module.Checks;
import jdk.jfr.internal.EventClassBuilder;
import jdk.jfr.internal.JVMSupport;
import jdk.jfr.internal.MetadataRepository;
import jdk.jfr.internal.Type;
import jdk.jfr.internal.Utils;

/**
 * Class for defining an event at runtime.
 * <p>
 * It's highly recommended that the event is defined at compile time, if the
 * field layout is known, so the Java Virtual Machine (JVM) can optimize the
 * code, possibly remove all instrumentation if Flight Recorder is inactive or
 * if the enabled setting for this event is set to {@code false}.
 * <p>
 * To define an event at compile time, see {@link Event}.
 * <p>
 * The following example shows how to implement a dynamic {@code Event} class.
 *
 * {@snippet class="Snippets" region="EventFactoryOverview"}
 *
 * @since 9
 */

public final class EventFactory {

    private static final long REGISTERED_ID = Type.getTypeId(Registered.class);

    private final Class<? extends Event> eventClass;
    private final MethodHandle constructorHandle;
    private final List<AnnotationElement> sanitizedAnnotation;
    private final List<ValueDescriptor> sanitizedFields;

    private EventFactory(Class<? extends Event> eventClass, List<AnnotationElement> sanitizedAnnotation, List<ValueDescriptor> sanitizedFields) throws IllegalAccessException, NoSuchMethodException, SecurityException {
        this.constructorHandle = MethodHandles.lookup().unreflectConstructor(eventClass.getConstructor());
        this.eventClass = eventClass;
        this.sanitizedAnnotation = sanitizedAnnotation;
        this.sanitizedFields = sanitizedFields;
    }

    /**
     * Creates an {@code EventFactory} object.
     * <p>
     * The order of the value descriptors specifies the index to use when setting
     * event values.
     *
     * @param annotationElements list of annotation elements that describes the
     *        annotations on the event, not {@code null}
     *
     * @param fields list of descriptors that describes the fields of the event, not
     *        {@code null}
     *
     * @return event factory, not {@code null}
     *
     * @throws IllegalArgumentException if the input is not valid. For example,
     *         input might not be valid if the field type or name is not valid in
     *         the Java language or an annotation element references a type that
     *         can't be found.
     *
     * @throws SecurityException if a security manager exists and the caller does
     *         not have {@code FlightRecorderPermission("registerEvent")}
     *
     * @see Event#set(int, Object)
     */

    public static EventFactory create(List<AnnotationElement> annotationElements, List<ValueDescriptor> fields) {
        Objects.requireNonNull(annotationElements, "annotationElements");
        Objects.requireNonNull(fields, "fields");
        JVMSupport.ensureWithInternalError();

        Utils.checkRegisterPermission();

        List<AnnotationElement> sanitizedAnnotation = Utils.sanitizeNullFreeList(annotationElements, AnnotationElement.class);
        List<ValueDescriptor> sanitizedFields = Utils.sanitizeNullFreeList(fields, ValueDescriptor.class);
        Set<String> nameSet = HashSet.newHashSet(sanitizedFields.size());
        for (ValueDescriptor v : sanitizedFields) {
            String name = v.getName();
            if (v.isArray()) {
                throw new IllegalArgumentException("Array types are not allowed for fields");
            }
            if (!Type.isValidJavaFieldType(v.getTypeName())) {
                throw new IllegalArgumentException(v.getTypeName() + " is not a valid type for an event field");
            }
            if (!Checks.isJavaIdentifier(v.getName())) {
                throw new IllegalArgumentException(name + " is not a valid name for an event field");
            }
            if (nameSet.contains(name)) {
                throw new IllegalArgumentException("Name of fields must be unique. Found two instances of " + name);
            }
            nameSet.add(name);
        }

        // Prevent event from being registered in <clinit>
        // and only use annotations that can be resolved (those in boot class loader)
        boolean needRegister = true;
        List<AnnotationElement> bootAnnotations = new ArrayList<>();
        for (AnnotationElement ae : sanitizedAnnotation) {
            long id = ae.getTypeId();
            if (ae.isInBoot()) {
                if (id == REGISTERED_ID) {
                    if (Boolean.FALSE.equals(ae.getValue("value"))) {
                        needRegister = false;
                    }
                } else {
                    bootAnnotations.add(ae);
                }
            }
        }
        bootAnnotations.add(new AnnotationElement(Registered.classfalse));

        EventClassBuilder ecb = new EventClassBuilder(bootAnnotations, sanitizedFields);
        Class<? extends Event> eventClass = ecb.build();

        if (needRegister) {
            MetadataRepository.getInstance().register(eventClass, sanitizedAnnotation, sanitizedFields);
        }
        try {
            return new EventFactory(eventClass, sanitizedAnnotation, sanitizedFields);
        } catch (IllegalAccessException e) {
            throw new IllegalAccessError("Could not access constructor of generated event class, " + e.getMessage());
        } catch (NoSuchMethodException e) {
            throw new InternalError("Could not find constructor in generated event class, " + e.getMessage());
        }
    }

    /**
     * Instantiates an event, so it can be populated with data and written to the
     * Flight Recorder system.
     * <p>
     * Use the {@link Event#set(int, Object)} method to set a value.
     *
     * @return an event instance, not {@code null}
     */

    public Event newEvent() {
        try {
            return (Event) constructorHandle.invoke();
        } catch (Throwable e) {
            throw new InstantiationError("Could not instantiate dynamically generated event class " + eventClass.getName() + ". " + e.getMessage());
        }
    }

    /**
     * Returns the event type that is associated with this event factory.
     *
     * @return event type that is associated with this event factory, not
     *         {@code null}
     *
     * @throws java.lang.IllegalStateException if the event factory is created with
     *         the {@code Registered(false)} annotation and the event class is not
     *         manually registered before the invocation of this method
     */

    public EventType getEventType() {
        return EventType.getEventType(eventClass);
    }

    /**
     * Registers an unregistered event.
     * <p>
     * By default, the event class associated with this event factory is registered
     * when the event factory is created, unless the event has the
     * {@link Registered} annotation.
     * <p>
     * A registered event class can write data to Flight Recorder and event metadata
     * can be obtained by invoking {@link FlightRecorder#getEventTypes()}.
     * <p>
     * If the event class associated with this event factory is already registered,
     * the call to this method is ignored.
     *
     * @throws SecurityException if a security manager exists and the caller
     *         does not have {@code FlightRecorderPermission("registerEvent")}
     * @see Registered
     * @see FlightRecorder#register(Class)
     */

    public void register() {
        MetadataRepository.getInstance().register(eventClass, sanitizedAnnotation, sanitizedFields);
    }

    /**
     * Unregisters the event that is associated with this event factory.
     * <p>
     * A unregistered event class can't write data to Flight Recorder and event
     * metadata can't be obtained by invoking
     * {@link FlightRecorder#getEventTypes()}.
     * <p>
     * If the event class associated with this event factory is not already
     * registered, the call to this method is ignored.
     *
     * @throws SecurityException if a security manager exists and the caller does
     *         not have {@code FlightRecorderPermission("registerEvent")}
     * @see Registered
     * @see FlightRecorder#unregister(Class)
     */

    public void unregister() {
        MetadataRepository.getInstance().unregister(eventClass);
    }
}

Messung V0.5
C=83 H=95 G=88

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.