jakarta.enterprise.inject.build.compatible.spi.Enhancement Maven / Gradle / Ivy
/*
* Copyright (c) 2021 Red Hat and others
*
* This program and the accompanying materials are made available under the
* Apache Software License 2.0 which is available at:
* https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: Apache-2.0
*/
package jakarta.enterprise.inject.build.compatible.spi;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 2nd phase of {@linkplain BuildCompatibleExtension build compatible extension} execution.
* Allows transforming annotations.
*
* In the following text, the term expected types denotes the set of types defined by
* the {@link #types() types}, {@link #withSubtypes() withSubtypes} and {@link #withAnnotations() withAnnotations}
* members of the {@code @Enhancement} annotation. The term discovered types denotes
* the subset of expected types that were discovered during type discovery.
*
* Methods annotated {@code @Enhancement} must declare exactly one parameter of one of these types:
*
* - {@link ClassConfig} or {@link jakarta.enterprise.lang.model.declarations.ClassInfo ClassInfo}
* - {@link MethodConfig} or {@link jakarta.enterprise.lang.model.declarations.MethodInfo MethodInfo}
* - {@link FieldConfig} or {@link jakarta.enterprise.lang.model.declarations.FieldInfo FieldInfo}
*
* If an {@code @Enhancement} method has a parameter of type {@code ClassConfig} or {@code ClassInfo},
* the method is called once for each discovered type.
*
* If an {@code @Enhancement} method has a parameter of type {@code MethodConfig} or {@code MethodInfo},
* the method is called once for each constructor or method that is declared on each discovered type,
* as defined in {@link jakarta.enterprise.lang.model.declarations.ClassInfo#constructors() ClassInfo.constructors}
* and {@link jakarta.enterprise.lang.model.declarations.ClassInfo#methods() ClassInfo.methods}.
*
* If an {@code @Enhancement} method has a parameter of type {@code FieldConfig} or {@code FieldInfo},
* the method is called once for each field that is declared on each discovered type, as defined
* in {@link jakarta.enterprise.lang.model.declarations.ClassInfo#fields() ClassInfo.fields}.
*
* If the {@code @Enhancement} method doesn't declare any parameter of one of these types,
* or if it declares more than one, the container treats it as a definition error.
*
* Additionally, methods annotated {@code @Enhancement} may declare parameters of these types:
*
* - {@link Messages}
* - {@link Types}
*
*
* Finally, {@link AnnotationBuilder} may be used to create instances
* of {@link jakarta.enterprise.lang.model.AnnotationInfo AnnotationInfo}.
*
* @since 4.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Enhancement {
/**
* Defines the set of expected types. If {@link #withSubtypes() withSubtypes}
* is {@code true}, the set of expected types includes all direct and indirect
* subtypes of these types. If {@link #withAnnotations() withAnnotations} is defined,
* the set of expected types only includes types that use given annotations.
*
* @return the set of expected types
*/
Class>[] types();
/**
* If {@code true}, the set of expected types includes all direct and
* indirect subtypes of given {@link #types() types}.
*
* @return whether subtypes should be included in the set of expected types
*/
boolean withSubtypes() default false;
/**
* Narrows down the set of expected types, defined by {@link #types() types}
* and {@link #withSubtypes() withSubtypes}, to types that use any of given annotations.
* The annotation can appear on the type, or on any member of the type, or on any
* parameter of any member of the type, or as a meta-annotation on any annotation
* that is considered by these rules.
*
* If empty, the set of expected types is not narrowed down in any way.
* If {@code java.lang.Annotation} is present, the set of expected types
* is narrowed down to types that use any annotation.
*
* Defaults to an empty array, so that the set of expected types is not
* narrowed down in any way.
*
* @return types of annotations that must be present on the expected types
*/
Class extends Annotation>[] withAnnotations() default {};
}