diff --git a/api/src/main/java/jakarta/annotation/CheckForNull.java b/api/src/main/java/jakarta/annotation/CheckForNull.java new file mode 100755 index 0000000..f3a95af --- /dev/null +++ b/api/src/main/java/jakarta/annotation/CheckForNull.java @@ -0,0 +1,21 @@ +package jakarta.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import jakarta.annotation.meta.TypeQualifierNickname; +import jakarta.annotation.meta.When; + +/** + * The annotated element might be null, and uses of the element should check for null. + *
+ * When this annotation is applied to a method it applies to the method return value. + */ +@Documented +@TypeQualifierNickname +@Nonnull(when = When.MAYBE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckForNull { + +} diff --git a/api/src/main/java/jakarta/annotation/CheckForSigned.java b/api/src/main/java/jakarta/annotation/CheckForSigned.java new file mode 100755 index 0000000..6d2ecc6 --- /dev/null +++ b/api/src/main/java/jakarta/annotation/CheckForSigned.java @@ -0,0 +1,23 @@ +package jakarta.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import jakarta.annotation.meta.TypeQualifierNickname; +import jakarta.annotation.meta.When; + +/** + * Used to annotate a value that may be either negative or nonnegative, and + * indicates that uses of it should check for + * negative values before using it in a way that requires the value to be + * nonnegative, and check for it being nonnegative before using it in a way that + * requires it to be negative. + */ +@Documented +@TypeQualifierNickname +@Nonnegative(when = When.MAYBE) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckForSigned { + +} diff --git a/api/src/main/java/jakarta/annotation/CheckReturnValue.java b/api/src/main/java/jakarta/annotation/CheckReturnValue.java new file mode 100755 index 0000000..faa434f --- /dev/null +++ b/api/src/main/java/jakarta/annotation/CheckReturnValue.java @@ -0,0 +1,21 @@ +package jakarta.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import jakarta.annotation.meta.When; + +/** + * This annotation is used to denote a method whose return value should always + * be checked after invoking the method. + */ +@Documented +@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE, + ElementType.PACKAGE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckReturnValue { + When when() default When.ALWAYS; +} diff --git a/api/src/main/java/jakarta/annotation/Detainted.java b/api/src/main/java/jakarta/annotation/Detainted.java new file mode 100755 index 0000000..69de79a --- /dev/null +++ b/api/src/main/java/jakarta/annotation/Detainted.java @@ -0,0 +1,16 @@ +package jakarta.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import jakarta.annotation.meta.TypeQualifierNickname; +import jakarta.annotation.meta.When; + +@Documented +@TypeQualifierNickname +@Untainted(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +public @interface Detainted { + +} diff --git a/api/src/main/java/jakarta/annotation/MatchesPattern.java b/api/src/main/java/jakarta/annotation/MatchesPattern.java new file mode 100755 index 0000000..b7c15ff --- /dev/null +++ b/api/src/main/java/jakarta/annotation/MatchesPattern.java @@ -0,0 +1,35 @@ +package jakarta.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.regex.Pattern; + +import jakarta.annotation.meta.TypeQualifier; +import jakarta.annotation.meta.TypeQualifierValidator; +import jakarta.annotation.meta.When; + +/** + * This annotation is used to denote String values that should always match given pattern. + *
+ * When this annotation is applied to a method it applies to the method return value.
+ */
+@Documented
+@TypeQualifier(applicableTo = String.class)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MatchesPattern {
+ @RegEx
+ String value();
+
+ int flags() default 0;
+
+ static class Checker implements TypeQualifierValidator
+ * When this annotation is applied to a method it applies to the method return value.
+ */
+@Documented
+@TypeQualifier(applicableTo = Number.class)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Nonnegative {
+ When when() default When.ALWAYS;
+
+ class Checker implements TypeQualifierValidator
+ * An example of such method is {@link Object#finalize()}.
+ */
+@Documented
+@Target( { ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OverridingMethodsMustInvokeSuper {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/ParametersAreNonnullByDefault.java b/api/src/main/java/jakarta/annotation/ParametersAreNonnullByDefault.java
new file mode 100755
index 0000000..882527a
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/ParametersAreNonnullByDefault.java
@@ -0,0 +1,28 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.meta.TypeQualifierDefault;
+
+/**
+ * This annotation can be applied to a package, class or method to indicate that
+ * the method parameters in that element are nonnull by default unless there is:
+ * This annotation implies the same "nullness" as no annotation. However, it is different
+ * than having no annotation, as it is inherited and it can override a {@link ParametersAreNonnullByDefault}
+ * annotation at an outer scope.
+ *
+ * @see Nullable
+ */
+@Documented
+@Nullable
+@TypeQualifierDefault(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ParametersAreNullableByDefault {
+}
diff --git a/api/src/main/java/jakarta/annotation/PropertyKey.java b/api/src/main/java/jakarta/annotation/PropertyKey.java
new file mode 100755
index 0000000..8795680
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/PropertyKey.java
@@ -0,0 +1,15 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.meta.TypeQualifier;
+import jakarta.annotation.meta.When;
+
+@Documented
+@TypeQualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PropertyKey {
+ When when() default When.ALWAYS;
+}
diff --git a/api/src/main/java/jakarta/annotation/RegEx.java b/api/src/main/java/jakarta/annotation/RegEx.java
new file mode 100755
index 0000000..700ed0d
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/RegEx.java
@@ -0,0 +1,43 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import jakarta.annotation.meta.TypeQualifierNickname;
+import jakarta.annotation.meta.TypeQualifierValidator;
+import jakarta.annotation.meta.When;
+
+/**
+ * This qualifier is used to denote String values that should be a Regular
+ * expression.
+ *
+ * When this annotation is applied to a method it applies to the method return value.
+ */
+@Documented
+@Syntax("RegEx")
+@TypeQualifierNickname
+@Retention(RetentionPolicy.RUNTIME)
+public @interface RegEx {
+ When when() default When.ALWAYS;
+
+ static class Checker implements TypeQualifierValidator
+ * Syntax names can be followed by a colon and a list of key value pairs,
+ * separated by commas. For example, "SQL:dialect=Oracle,version=2.3". Tools
+ * should ignore any keys they don't recognize.
+ *
+ * @return a name indicating the particular syntax.
+ */
+ String value();
+
+ When when() default When.ALWAYS;
+}
diff --git a/api/src/main/java/jakarta/annotation/Tainted.java b/api/src/main/java/jakarta/annotation/Tainted.java
new file mode 100755
index 0000000..e87acea
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/Tainted.java
@@ -0,0 +1,27 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.meta.TypeQualifierNickname;
+import jakarta.annotation.meta.When;
+
+/**
+ * This annotation is used to denote String values that are tainted, i.e. may come
+ * from untrusted sources without proper validation.
+ *
+ * For example, this annotation should be used on the String value which
+ * represents raw input received from the web form.
+ *
+ * When this annotation is applied to a method it applies to the method return value.
+ *
+ * @see Untainted
+ */
+@Documented
+@TypeQualifierNickname
+@Untainted(when = When.MAYBE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Tainted {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/Untainted.java b/api/src/main/java/jakarta/annotation/Untainted.java
new file mode 100755
index 0000000..a041f27
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/Untainted.java
@@ -0,0 +1,26 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.meta.TypeQualifier;
+import jakarta.annotation.meta.When;
+
+/**
+ * This annotation is used to denote String values that are untainted,
+ * i.e. properly validated.
+ *
+ * For example, this annotation should be used on the String value which
+ * represents SQL query to be passed to database engine.
+ *
+ * When this annotation is applied to a method it applies to the method return value.
+ *
+ * @see Tainted
+ */
+@Documented
+@TypeQualifier
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Untainted {
+ When when() default When.ALWAYS;
+}
diff --git a/api/src/main/java/jakarta/annotation/WillClose.java b/api/src/main/java/jakarta/annotation/WillClose.java
new file mode 100755
index 0000000..0b09ec1
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/WillClose.java
@@ -0,0 +1,18 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to annotate a method parameter to indicate that this method will close
+ * the resource.
+ *
+ * @see WillCloseWhenClosed
+ * @see WillNotClose
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WillClose {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/WillCloseWhenClosed.java b/api/src/main/java/jakarta/annotation/WillCloseWhenClosed.java
new file mode 100755
index 0000000..93ac682
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/WillCloseWhenClosed.java
@@ -0,0 +1,18 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to annotate a constructor/factory parameter to indicate that returned
+ * object (X) will close the resource when X is closed.
+ *
+ * @see WillClose
+ * @see WillNotClose
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WillCloseWhenClosed {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/WillNotClose.java b/api/src/main/java/jakarta/annotation/WillNotClose.java
new file mode 100755
index 0000000..d715639
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/WillNotClose.java
@@ -0,0 +1,18 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Used to annotate a method parameter to indicate that this method will not
+ * close the resource.
+ *
+ * @see WillClose
+ * @see WillCloseWhenClosed
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface WillNotClose {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/concurrent/GuardedBy.java b/api/src/main/java/jakarta/annotation/concurrent/GuardedBy.java
new file mode 100755
index 0000000..ac7a261
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/concurrent/GuardedBy.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005 Brian Goetz
+ * Released under the Creative Commons Attribution License
+ * (http://creativecommons.org/licenses/by/2.5)
+ * Official home: http://www.jcip.net
+ */
+package jakarta.annotation.concurrent;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The field or method to which this annotation is applied can only be accessed
+ * when holding a particular lock, which may be a built-in (synchronization)
+ * lock, or may be an explicit {@link java.util.concurrent.locks.Lock}.
+ *
+ * The argument determines which lock guards the annotated field or method:
+ *
+ * Immutable objects are inherently thread-safe; they may be passed between
+ * threads or published without synchronization.
+ */
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface Immutable {
+}
diff --git a/api/src/main/java/jakarta/annotation/concurrent/NotThreadSafe.java b/api/src/main/java/jakarta/annotation/concurrent/NotThreadSafe.java
new file mode 100755
index 0000000..b1f554e
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/concurrent/NotThreadSafe.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2005 Brian Goetz
+ * Released under the Creative Commons Attribution License
+ * (http://creativecommons.org/licenses/by/2.5)
+ * Official home: http://www.jcip.net
+ */
+package jakarta.annotation.concurrent;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The class to which this annotation is applied is not thread-safe. This
+ * annotation primarily exists for clarifying the non-thread-safety of a class
+ * that might otherwise be assumed to be thread-safe, despite the fact that it
+ * is a bad idea to assume a class is thread-safe without good reason.
+ *
+ * @see ThreadSafe
+ */
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface NotThreadSafe {
+}
diff --git a/api/src/main/java/jakarta/annotation/concurrent/ThreadSafe.java b/api/src/main/java/jakarta/annotation/concurrent/ThreadSafe.java
new file mode 100755
index 0000000..f1e4eb9
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/concurrent/ThreadSafe.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2005 Brian Goetz
+ * Released under the Creative Commons Attribution License
+ * (http://creativecommons.org/licenses/by/2.5)
+ * Official home: http://www.jcip.net
+ */
+package jakarta.annotation.concurrent;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The class to which this annotation is applied is thread-safe. This means that
+ * no sequences of accesses (reads and writes to public fields, calls to public
+ * methods) may put the object into an invalid state, regardless of the
+ * interleaving of those actions by the runtime, and without requiring any
+ * additional synchronization or coordination on the part of the caller.
+ *
+ * @see NotThreadSafe
+ */
+@Documented
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface ThreadSafe {
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/Exclusive.java b/api/src/main/java/jakarta/annotation/meta/Exclusive.java
new file mode 100755
index 0000000..171009e
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/Exclusive.java
@@ -0,0 +1,27 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation can be applied to the value() element of an annotation that
+ * is annotated as a TypeQualifier.
+ *
+ *
+ * For example, the following defines a type qualifier such that if you know a
+ * value is {@literal @Foo(1)}, then the value cannot be {@literal @Foo(2)} or {{@literal @Foo(3)}.
+ *
+ *
+ * Applications of the type qualifier with different values are exclusive, and
+ * the enumeration is an exhaustive list of the possible values.
+ *
+ *
+ * For example, the following defines a type qualifier such that if you know a
+ * value is neither {@literal @Foo(Color.Red)} or {@literal @Foo(Color.Blue)},
+ * then the value must be {@literal @Foo(Color.Green)}. And if you know it is
+ * {@literal @Foo(Color.Green)}, you know it cannot be
+ * {@literal @Foo(Color.Red)} or {@literal @Foo(Color.Blue)}
+ *
+ *
+ * Thus, you might define a qualifier SocialSecurityNumber as follows:
+ *
+ *
+ *
+ * @see Nonnull
+ */
+@Documented
+@Nonnull
+@TypeQualifierDefault(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ParametersAreNonnullByDefault {
+}
diff --git a/api/src/main/java/jakarta/annotation/ParametersAreNullableByDefault.java b/api/src/main/java/jakarta/annotation/ParametersAreNullableByDefault.java
new file mode 100755
index 0000000..1682fd7
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/ParametersAreNullableByDefault.java
@@ -0,0 +1,30 @@
+package jakarta.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import jakarta.annotation.meta.TypeQualifierDefault;
+
+/**
+ * This annotation can be applied to a package, class or method to indicate that
+ * the method parameters in that element are nullable by default unless there is:
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+@Target( { ElementType.FIELD, ElementType.METHOD })
+@Retention(RetentionPolicy.CLASS)
+public @interface GuardedBy {
+ String value();
+}
diff --git a/api/src/main/java/jakarta/annotation/concurrent/Immutable.java b/api/src/main/java/jakarta/annotation/concurrent/Immutable.java
new file mode 100755
index 0000000..5e22782
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/concurrent/Immutable.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2005 Brian Goetz
+ * Released under the Creative Commons Attribution License
+ * (http://creativecommons.org/licenses/by/2.5)
+ * Official home: http://www.jcip.net
+ */
+package jakarta.annotation.concurrent;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * The class to which this annotation is applied is immutable. This means that
+ * its state cannot be seen to change by callers. Of necessity this means that
+ * all public fields are final, and that all public final reference fields refer
+ * to other immutable objects, and that methods do not publish references to any
+ * internal state which is mutable by implementation even if not by design.
+ * Immutable objects may still have internal mutable state for purposes of
+ * performance optimization; some state variables may be lazily computed, so
+ * long as they are computed from immutable state and that callers cannot tell
+ * the difference.
+ *
+ * @TypeQualifier @interface Foo {
+ * @Exclusive int value();
+ * }
+ *
+ *
+ */
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Exclusive {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/Exhaustive.java b/api/src/main/java/jakarta/annotation/meta/Exhaustive.java
new file mode 100755
index 0000000..12402ea
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/Exhaustive.java
@@ -0,0 +1,35 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This annotation can be applied to the value() element of an annotation that
+ * is annotated as a TypeQualifier. This is only appropriate if the value field
+ * returns a value that is an Enumeration.
+ *
+ *
+ * @TypeQualifier @interface Foo {
+ * enum Color {RED, BLUE, GREEN};
+ * @Exhaustive Color value();
+ * }
+ *
+ */
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Exhaustive {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/TypeQualifier.java b/api/src/main/java/jakarta/annotation/meta/TypeQualifier.java
new file mode 100755
index 0000000..057346a
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/TypeQualifier.java
@@ -0,0 +1,29 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This qualifier is applied to an annotation to denote that the annotation
+ * should be treated as a type qualifier.
+ */
+@Documented
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TypeQualifier {
+
+ /**
+ * Describes the kinds of values the qualifier can be applied to. If a
+ * numeric class is provided (e.g., Number.class or Integer.class) then the
+ * annotation can also be applied to the corresponding primitive numeric
+ * types.
+ *
+ * @return a class object which denotes the type of the values
+ * the original annotation can be applied to.
+ */
+ Class> applicableTo() default Object.class;
+
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/TypeQualifierDefault.java b/api/src/main/java/jakarta/annotation/meta/TypeQualifierDefault.java
new file mode 100755
index 0000000..ef9a00b
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/TypeQualifierDefault.java
@@ -0,0 +1,20 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * This qualifier is applied to an annotation to denote that the annotation
+ * defines a default type qualifier that is visible within the scope of the
+ * element it is applied to.
+ */
+
+@Documented
+@Target(ElementType.ANNOTATION_TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface TypeQualifierDefault {
+ ElementType[] value() default {};
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/TypeQualifierNickname.java b/api/src/main/java/jakarta/annotation/meta/TypeQualifierNickname.java
new file mode 100755
index 0000000..395c6d4
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/TypeQualifierNickname.java
@@ -0,0 +1,29 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is applied to a annotation, and marks the annotation as being
+ * a qualifier nickname. Applying a nickname annotation X to a element Y should
+ * be interpreted as having the same meaning as applying all of annotations of X
+ * (other than QualifierNickname) to Y.
+ *
+ *
+ * @Documented
+ * @TypeQualifierNickname @Pattern("[0-9]{3}-[0-9]{2}-[0-9]{4}")
+ * @Retention(RetentionPolicy.RUNTIME)
+ * public @interface SocialSecurityNumber {
+ * }
+ *
+ */
+@Documented
+@Target(ElementType.ANNOTATION_TYPE)
+public @interface TypeQualifierNickname {
+
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/TypeQualifierValidator.java b/api/src/main/java/jakarta/annotation/meta/TypeQualifierValidator.java
new file mode 100755
index 0000000..938d0c5
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/TypeQualifierValidator.java
@@ -0,0 +1,21 @@
+package jakarta.annotation.meta;
+
+import java.lang.annotation.Annotation;
+
+import jakarta.annotation.Nonnull;
+
+public interface TypeQualifierValidator {
+ /**
+ * Given a type qualifier, check to see if a known specific constant value
+ * is an instance of the set of values denoted by the qualifier.
+ *
+ * @param annotation
+ * the type qualifier
+ * @param value
+ * the value to check
+ * @return a value indicating whether or not the value is an member of the
+ * values denoted by the type qualifier
+ */
+ public @Nonnull
+ When forConstantValue(@Nonnull A annotation, Object value);
+}
diff --git a/api/src/main/java/jakarta/annotation/meta/When.java b/api/src/main/java/jakarta/annotation/meta/When.java
new file mode 100755
index 0000000..7fcbed0
--- /dev/null
+++ b/api/src/main/java/jakarta/annotation/meta/When.java
@@ -0,0 +1,23 @@
+package jakarta.annotation.meta;
+
+/**
+ * Used to describe the relationship between a qualifier T and the set of values
+ * S possible on an annotated element.
+ *
+ * In particular, an issues should be reported if an ALWAYS or MAYBE value is
+ * used where a NEVER value is required, or if a NEVER or MAYBE value is used
+ * where an ALWAYS value is required.
+ *
+ *
+ */
+public enum When {
+ /** S is a subset of T */
+ ALWAYS,
+ /** nothing definitive is known about the relation between S and T */
+ UNKNOWN,
+ /** S intersection T is non empty and S - T is nonempty */
+ MAYBE,
+ /** S intersection T is empty */
+ NEVER;
+
+}