diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java new file mode 100644 index 00000000..457179f9 --- /dev/null +++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/AnnotationBuilder.java @@ -0,0 +1,763 @@ +package jakarta.enterprise.inject.build.compatible.spi; + +import jakarta.enterprise.lang.model.AnnotationInfo; +import jakarta.enterprise.lang.model.AnnotationMemberValue; +import jakarta.enterprise.lang.model.declarations.ClassInfo; +import jakarta.enterprise.lang.model.types.Type; + +import java.lang.annotation.Annotation; + +/** + * Builder for annotations of given type. + * Expected usage is: + *
* If you need to create instances of {@link jakarta.enterprise.lang.model.types.Type Type}, you can also declare - * a parameter of type {@link Types Types}. It provides factory methods for the void type, primitive types, + * a parameter of type {@link Types}. It provides factory methods for the void type, primitive types, * class types, array types, parameterized types and wildcard types. *
- * If you need to create instances of {@link jakarta.enterprise.lang.model.AnnotationMember AnnotationAttribute} or
- * {@link jakarta.enterprise.lang.model.AnnotationMemberValue AnnotationAttributeValue}, you can also declare
- * a parameter of type {@link Annotations Annotations}. It provides factory methods for all kinds of annotation attributes.
+ * If you need to create instances of {@link jakarta.enterprise.lang.model.AnnotationInfo AnnotationInfo},
+ * use {@link AnnotationBuilder}.
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java
index 10fed9fc..2f677156 100644
--- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java
+++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/MetaAnnotations.java
@@ -45,6 +45,8 @@ public interface MetaAnnotations {
/**
* Registers custom context as configured by the returned {@link ContextConfig}.
+ *
+ * @return custom context configurator, never {@code null}
*/
ContextConfig addContext();
}
diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java
index 45c07317..b0a88c06 100644
--- a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java
+++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/ScopeInfo.java
@@ -4,14 +4,18 @@
public interface ScopeInfo {
/**
- * @return declaration of the scope annotation
+ * Returns the declaration of this scope annotation's type.
+ *
+ * @return declaration of this scope annotation's type, never {@code null}
*/
ClassInfo> annotation();
/**
+ * Binary name of this scope annotation's type, as defined by The Java™ Language Specification;
+ * in other words, the scope annotation type name as returned by {@link Class#getName()}.
* Equivalent to {@code annotation().name()}.
*
- * @return fully qualified name of the annotation
+ * @return binary name of this scope annotation's type, never {@code null}
*/
default String name() {
return annotation().name();
@@ -19,7 +23,7 @@ default String name() {
/**
* Returns whether the scope is normal. In other words, returns whether
- * the scope annotation type is meta-annotated with {@code @NormalScope}.
+ * the scope annotation type is meta-annotated {@code @NormalScope}.
*
* @return whether the scope is normal
*/
diff --git a/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SecurityActions.java b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SecurityActions.java
new file mode 100644
index 00000000..d7fd5135
--- /dev/null
+++ b/api/src/main/java/jakarta/enterprise/inject/build/compatible/spi/SecurityActions.java
@@ -0,0 +1,39 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2018, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.1-SNAPSHOT (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.1-SNAPSHOT
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package jakarta.enterprise.inject.build.compatible.spi;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ServiceLoader;
+
+/**
+ * This utility class is used to optimize invocation made through the SecurityManager
+ *
+ * @author Antoine Sabot-durand
+ */
+
+final class SecurityActions {
+ private SecurityActions() {
+ }
+
+ static
+ *
+ * The {@link #kind()} method returns the kind of this annotation member value.
+ * The {@code is*} methods (such as {@link #isBoolean()}) allow checking
+ * if this annotation member value is of given kind. The {@code as*} methods
+ * (such as {@link #asBoolean()} allow "unwrapping" this annotation member value,
+ * if it is of the corresponding kind.
+ *
+ * TODO do the as* methods allow coercion or not? E.g., does asLong return a long
+ * if the value is of kind int, or does it throw? Fortunately, this only applies
+ * to the numeric primitive types and maybe String. I currently left the numeric
+ * as* methods documented as coercing, while asString as not coercing, but this
+ * needs more discussion. I personally don't like coercion here and would always
+ * throw if the type mismatches.
*/
public interface AnnotationMemberValue {
/**
- * The kind of the member.
+ * The kind of the annotation member value.
*/
enum Kind {
/**
- * A primitive {@link java.lang.Boolean}.
+ * A primitive {@code boolean}.
*/
BOOLEAN,
/**
- * A primitive {@link java.lang.Byte}.
+ * A primitive {@code byte}.
*/
BYTE,
/**
- * A primitive {@link java.lang.Short}.
+ * A primitive {@code short}.
*/
SHORT,
/**
- * A primitive {@link java.lang.Integer}.
+ * A primitive {@code int}.
*/
INT,
/**
- * A primitive {@link java.lang.Long}.
+ * A primitive {@code long}.
*/
LONG,
/**
- * A primitive {@link java.lang.Float}.
+ * A primitive {@code float}.
*/
FLOAT,
/**
- * A primitive {@link java.lang.Double}.
+ * A primitive {@code double}.
*/
DOUBLE,
/**
- * A primitive {@link java.lang.Character}.
+ * A primitive {@code char}.
*/
CHAR,
/**
- * A {@link java.lang.String} value.
+ * A {@link String} value.
*/
STRING,
/**
- * An {@link java.lang.Enum} value.
+ * An {@link Enum} value.
*/
ENUM,
/**
- * A {@link java.lang.Class} value modelled as {@link jakarta.enterprise.lang.model.types.Type}.
+ * A {@link Class} value. Represented as {@link jakarta.enterprise.lang.model.types.Type}.
*/
CLASS,
/**
- * An array value.
+ * A nested {@link java.lang.annotation.Annotation Annotation} value.
+ * Represented as {@link AnnotationInfo}.
*/
- ARRAY,
+ NESTED_ANNOTATION,
/**
- * A nested annotation definition.
+ * An array value.
*/
- NESTED_ANNOTATION,
+ ARRAY,
}
/**
- * @return The kind of the annotation member. Never {@code null}.
+ * Returns the kind of the annotation member value.
+ *
+ * @return the kind of the annotation member value, never {@code null}
*/
Kind kind();
/**
- * @return Returns {@code true} if the kind is a {@code boolean}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code boolean}, {@code false} otherwise
*/
default boolean isBoolean() {
return kind() == Kind.BOOLEAN;
}
/**
- * @return Returns {@code true} if the kind is a {@code byte}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code byte}, {@code false} otherwise
*/
default boolean isByte() {
return kind() == Kind.BYTE;
}
/**
- * @return Returns {@code true} if the kind is a {@code short}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code short}, {@code false} otherwise
*/
default boolean isShort() {
return kind() == Kind.SHORT;
}
/**
- * @return Returns {@code true} if the kind is a {@code int}, {@code false} otherwise.
+ * @return {@code true} if the kind is an {@code int}, {@code false} otherwise
*/
default boolean isInt() {
return kind() == Kind.INT;
}
/**
- * @return Returns {@code true} if the kind is a {@code long}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code long}, {@code false} otherwise
*/
default boolean isLong() {
return kind() == Kind.LONG;
}
/**
- * @return Returns {@code true} if the kind is a {@code float}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code float}, {@code false} otherwise
*/
default boolean isFloat() {
return kind() == Kind.FLOAT;
}
/**
- * @return Returns {@code true} if the kind is a {@code double}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code double}, {@code false} otherwise
*/
default boolean isDouble() {
return kind() == Kind.DOUBLE;
}
/**
- * @return Returns {@code true} if the kind is a {@code char}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@code char}, {@code false} otherwise
*/
default boolean isChar() {
return kind() == Kind.CHAR;
}
/**
- * @return Returns {@code true} if the kind is a {@link String}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@link String}, {@code false} otherwise
*/
default boolean isString() {
return kind() == Kind.STRING;
}
/**
- * @return Returns {@code true} if the kind is a {@link Enum}, {@code false} otherwise.
+ * @return {@code true} if the kind is an {@link Enum}, {@code false} otherwise
*/
default boolean isEnum() {
return kind() == Kind.ENUM;
}
/**
- * @return Returns {@code true} if the kind is a {@link Class}, {@code false} otherwise.
+ * @return {@code true} if the kind is a {@link Class}, {@code false} otherwise
*/
default boolean isClass() {
return kind() == Kind.CLASS;
}
/**
- * @return Returns {@code true} if the kind is an array, {@code false} otherwise.
+ * @return {@code true} if the kind is a nested {@link java.lang.annotation.Annotation Annotation}, {@code false} otherwise
*/
- default boolean isArray() {
- return kind() == Kind.ARRAY;
+ default boolean isNestedAnnotation() {
+ return kind() == Kind.NESTED_ANNOTATION;
}
/**
- * @return Returns {@code true} if the kind is an {@link java.lang.annotation.Annotation}, {@code false} otherwise.
+ * @return {@code true} if the kind is an array, {@code false} otherwise
*/
- default boolean isNestedAnnotation() {
- return kind() == Kind.NESTED_ANNOTATION;
+ default boolean isArray() {
+ return kind() == Kind.ARRAY;
}
/**
- * Return the value as a boolean.
- * @return The boolean value
+ * Returns the value as a boolean.
+ *
+ * @return the boolean value
+ * @throws IllegalStateException if this annotation member value is not a boolean
*/
boolean asBoolean();
/**
- * Return the value as a byte.
- * @return The byte value
- * @throws NumberFormatException if the value cannot be represented as a byte.
+ * Returns the value as a byte.
+ *
+ * @return the byte value
+ * @throws IllegalStateException if the value cannot be represented as a byte
*/
byte asByte();
/**
- * Return the value as a short.
- * @return The short value
- * @throws NumberFormatException if the value cannot be represented as a short.
+ * Returns the value as a short.
+ *
+ * @return the short value
+ * @throws IllegalStateException if the value cannot be represented as a short.
*/
short asShort();
/**
- * Return the value as an int.
- * @return The int value
- * @throws java.lang.IllegalStateException if the value cannot be represented as an int.
+ * Returns the value as an int.
+ *
+ * @return the int value
+ * @throws IllegalStateException if the value cannot be represented as an int.
*/
int asInt();
/**
- * Return the value as a long.
- * @return The long value
- * @throws java.lang.IllegalStateException if the value cannot be represented as a long.
+ * Returns the value as a long.
+ *
+ * @return the long value
+ * @throws IllegalStateException if the value cannot be represented as a long.
*/
long asLong();
/**
- * Return the value as a float.
- * @return The float value
- * @throws java.lang.IllegalStateException if the value cannot be represented as a float.
+ * Returns the value as a float.
+ *
+ * @return the float value
+ * @throws IllegalStateException if the value cannot be represented as a float.
*/
float asFloat();
/**
- * Return the value as a double.
- * @return The double value
- * @throws java.lang.IllegalStateException if the value cannot be represented as a double.
+ * Returns the value as a double.
+ *
+ * @return the double value
+ * @throws IllegalStateException if the value cannot be represented as a double.
*/
double asDouble();
/**
- * Return the value as a char.
- * @return The char value
- * @throws java.lang.IllegalStateException if the value cannot be represented as a double.
+ * Returns the value as a char.
+ *
+ * @return the char value
+ * @throws IllegalStateException if this annotation member value is not a char
*/
char asChar();
/**
- * Return the value as a string.
- * @return A string representing the value. Never {@code null}.
+ * Returns the value as a String.
+ *
+ * @return the String value
+ * @throws IllegalStateException if this annotation member value is not a String
*/
String asString();
/**
- * Return the value to an enum instance.
- * @param enumType The enum type
- * @param
+ *
*
- * @return An immutable list of {@link jakarta.enterprise.lang.model.AnnotationMemberValue} representing the array values.
+ * @return the class value, as a {@link Type}
+ * @throws IllegalStateException if this annotation member value is not a class value
*/
- List
@@ -16,88 +17,100 @@
*
*
+ * Annotations are represented as {@link AnnotationInfo}, so that implementations of this API are not required
+ * to instantiate the annotation type.
*
* @since 4.0.0
*/
public interface AnnotationTarget {
// TODO specify equals/hashCode (for the entire .lang.model hierarchy)
- // TODO settle on using Optional everywhere, or allowing null everywhere; it's a mix right now
- // TODO what about declared vs not declared annotations?
+ // TODO we decided that we won't use Optional and will just return null; need to make this consistent everywhere
+ // TODO what about declared vs not declared (inherited) annotations?
+ // probably should always return all, including inherited, that's what Portable Extensions do
/**
- * Returns whether this annotation target a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}.
+ * Returns whether this annotation target is a {@link DeclarationInfo declaration}.
*
+ * @return {@code true} if this is a declaration, {@code false} otherwise
* @see jakarta.enterprise.lang.model.declarations.DeclarationInfo
- * @return Will return {@code true} if it is a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo} and {@code false} otherwise
*/
boolean isDeclaration();
/**
- * Returns whether this annotation target is a {@link jakarta.enterprise.lang.model.types.Type}.
- * @return Will return {@code true} if it is a {@link jakarta.enterprise.lang.model.types.Type} and {@code false} otherwise
+ * Returns whether this annotation target is a {@link Type type}.
+ *
+ * @return {@code true} if this is a type, {@code false} otherwise
+ * @see jakarta.enterprise.lang.model.types.Type
*/
boolean isType();
/**
- * Coerce this annotation target to a {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo}.
- * @return The {@link jakarta.enterprise.lang.model.declarations.DeclarationInfo} instance, never {@code null}
- * @throws java.lang.IllegalStateException If {@link #isDeclaration()} returns {@code false}
+ * Returns this annotation target as a {@link DeclarationInfo declaration}.
+ *
+ * @return this declaration, never {@code null}
+ * @throws IllegalStateException if {@link #isDeclaration()} returns {@code false}
*/
DeclarationInfo asDeclaration();
/**
- * Coerce this annotation target to a {@link jakarta.enterprise.lang.model.types.Type}.
- * @return The {@link jakarta.enterprise.lang.model.types.Type} instance, never {@code null}
- * @throws java.lang.IllegalStateException If {@link #isType()} returns {@code false}
+ * Returns this annotation target as a {@link Type type}.
+ *
+ * @return this type, never {@code null}
+ * @throws IllegalStateException if {@link #isType()} returns {@code false}
*/
Type asType();
/**
- * Return with the given annotation type is present on this annotation target.
+ * Returns whether an annotation of given type is present on this annotation target.
*
- * @param annotationType The annotation type, never {@code null}
- * @return Returns {@code true} if the given annotation type is present on this annotation info, {@code false} otherwise.
- * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument
+ * @param annotationType the annotation type, must not be {@code null}
+ * @return {@code true} if given annotation type is present on this annotation target, {@code false} otherwise
*/
boolean hasAnnotation(Class extends Annotation> annotationType);
/**
- * Evaluate the given predicate, returning {@code true} if the predicate matches any {@link jakarta.enterprise.lang.model.AnnotationInfo} present on this annotation target.
- * @param predicate The predicate, never {@code null}
- * @return Returns {@code true} if the given predicate matches any {@link jakarta.enterprise.lang.model.AnnotationInfo} instance, {@code false} otherwise.
- * @throws java.lang.IllegalArgumentException If {@code null} is passed as an argument
+ * Returns whether given predicate matches any annotation present on this annotation target.
+ *
+ * @param predicate annotation predicate, must not be {@code null}
+ * @return {@code true} if given predicate matches any annotation present on this annotation target, {@code false} otherwise.
*/
boolean hasAnnotation(Predicate