From d07243b9b0e94d015ad9007d971bf4619442480a Mon Sep 17 00:00:00 2001 From: earcam Date: Tue, 17 Jul 2018 10:47:12 +0100 Subject: [PATCH] Adding com.google.code.findbugs:jsr305 --- .../java/javax/annotation/CheckForNull.java | 21 +++++++++ .../java/javax/annotation/CheckForSigned.java | 23 ++++++++++ .../javax/annotation/CheckReturnValue.java | 21 +++++++++ src/main/java/javax/annotation/Detainted.java | 16 +++++++ .../java/javax/annotation/MatchesPattern.java | 35 +++++++++++++++ .../java/javax/annotation/Nonnegative.java | 45 +++++++++++++++++++ src/main/java/javax/annotation/Nonnull.java | 32 +++++++++++++ src/main/java/javax/annotation/Nullable.java | 31 +++++++++++++ .../OverridingMethodsMustInvokeSuper.java | 21 +++++++++ .../ParametersAreNonnullByDefault.java | 28 ++++++++++++ .../ParametersAreNullableByDefault.java | 30 +++++++++++++ .../java/javax/annotation/PropertyKey.java | 15 +++++++ src/main/java/javax/annotation/RegEx.java | 43 ++++++++++++++++++ src/main/java/javax/annotation/Signed.java | 19 ++++++++ src/main/java/javax/annotation/Syntax.java | 45 +++++++++++++++++++ src/main/java/javax/annotation/Tainted.java | 27 +++++++++++ src/main/java/javax/annotation/Untainted.java | 26 +++++++++++ src/main/java/javax/annotation/WillClose.java | 18 ++++++++ .../javax/annotation/WillCloseWhenClosed.java | 18 ++++++++ .../java/javax/annotation/WillNotClose.java | 18 ++++++++ .../annotation/concurrent/GuardedBy.java | 35 +++++++++++++++ .../annotation/concurrent/Immutable.java | 33 ++++++++++++++ .../annotation/concurrent/NotThreadSafe.java | 27 +++++++++++ .../annotation/concurrent/ThreadSafe.java | 28 ++++++++++++ .../java/javax/annotation/meta/Exclusive.java | 27 +++++++++++ .../javax/annotation/meta/Exhaustive.java | 35 +++++++++++++++ .../javax/annotation/meta/TypeQualifier.java | 29 ++++++++++++ .../annotation/meta/TypeQualifierDefault.java | 20 +++++++++ .../meta/TypeQualifierNickname.java | 29 ++++++++++++ .../meta/TypeQualifierValidator.java | 21 +++++++++ src/main/java/javax/annotation/meta/When.java | 23 ++++++++++ 31 files changed, 839 insertions(+) create mode 100644 src/main/java/javax/annotation/CheckForNull.java create mode 100644 src/main/java/javax/annotation/CheckForSigned.java create mode 100644 src/main/java/javax/annotation/CheckReturnValue.java create mode 100644 src/main/java/javax/annotation/Detainted.java create mode 100644 src/main/java/javax/annotation/MatchesPattern.java create mode 100644 src/main/java/javax/annotation/Nonnegative.java create mode 100644 src/main/java/javax/annotation/Nonnull.java create mode 100644 src/main/java/javax/annotation/Nullable.java create mode 100644 src/main/java/javax/annotation/OverridingMethodsMustInvokeSuper.java create mode 100644 src/main/java/javax/annotation/ParametersAreNonnullByDefault.java create mode 100644 src/main/java/javax/annotation/ParametersAreNullableByDefault.java create mode 100644 src/main/java/javax/annotation/PropertyKey.java create mode 100644 src/main/java/javax/annotation/RegEx.java create mode 100644 src/main/java/javax/annotation/Signed.java create mode 100644 src/main/java/javax/annotation/Syntax.java create mode 100644 src/main/java/javax/annotation/Tainted.java create mode 100644 src/main/java/javax/annotation/Untainted.java create mode 100644 src/main/java/javax/annotation/WillClose.java create mode 100644 src/main/java/javax/annotation/WillCloseWhenClosed.java create mode 100644 src/main/java/javax/annotation/WillNotClose.java create mode 100644 src/main/java/javax/annotation/concurrent/GuardedBy.java create mode 100644 src/main/java/javax/annotation/concurrent/Immutable.java create mode 100644 src/main/java/javax/annotation/concurrent/NotThreadSafe.java create mode 100644 src/main/java/javax/annotation/concurrent/ThreadSafe.java create mode 100644 src/main/java/javax/annotation/meta/Exclusive.java create mode 100644 src/main/java/javax/annotation/meta/Exhaustive.java create mode 100644 src/main/java/javax/annotation/meta/TypeQualifier.java create mode 100644 src/main/java/javax/annotation/meta/TypeQualifierDefault.java create mode 100644 src/main/java/javax/annotation/meta/TypeQualifierNickname.java create mode 100644 src/main/java/javax/annotation/meta/TypeQualifierValidator.java create mode 100644 src/main/java/javax/annotation/meta/When.java diff --git a/src/main/java/javax/annotation/CheckForNull.java b/src/main/java/javax/annotation/CheckForNull.java new file mode 100644 index 0000000..4debd3e --- /dev/null +++ b/src/main/java/javax/annotation/CheckForNull.java @@ -0,0 +1,21 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.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/src/main/java/javax/annotation/CheckForSigned.java b/src/main/java/javax/annotation/CheckForSigned.java new file mode 100644 index 0000000..20dca9b --- /dev/null +++ b/src/main/java/javax/annotation/CheckForSigned.java @@ -0,0 +1,23 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.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/src/main/java/javax/annotation/CheckReturnValue.java b/src/main/java/javax/annotation/CheckReturnValue.java new file mode 100644 index 0000000..455a417 --- /dev/null +++ b/src/main/java/javax/annotation/CheckReturnValue.java @@ -0,0 +1,21 @@ +package javax.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 javax.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/src/main/java/javax/annotation/Detainted.java b/src/main/java/javax/annotation/Detainted.java new file mode 100644 index 0000000..d8620f2 --- /dev/null +++ b/src/main/java/javax/annotation/Detainted.java @@ -0,0 +1,16 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +@Documented +@TypeQualifierNickname +@Untainted(when = When.ALWAYS) +@Retention(RetentionPolicy.RUNTIME) +public @interface Detainted { + +} diff --git a/src/main/java/javax/annotation/MatchesPattern.java b/src/main/java/javax/annotation/MatchesPattern.java new file mode 100644 index 0000000..b899036 --- /dev/null +++ b/src/main/java/javax/annotation/MatchesPattern.java @@ -0,0 +1,35 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.regex.Pattern; + +import javax.annotation.meta.TypeQualifier; +import javax.annotation.meta.TypeQualifierValidator; +import javax.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 { + public When forConstantValue(MatchesPattern annotation, Object value) { + Pattern p = Pattern.compile(annotation.value(), annotation.flags()); + if (p.matcher(((String) value)).matches()) + return When.ALWAYS; + return When.NEVER; + } + + } +} diff --git a/src/main/java/javax/annotation/Nonnegative.java b/src/main/java/javax/annotation/Nonnegative.java new file mode 100644 index 0000000..30424f1 --- /dev/null +++ b/src/main/java/javax/annotation/Nonnegative.java @@ -0,0 +1,45 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifier; +import javax.annotation.meta.TypeQualifierValidator; +import javax.annotation.meta.When; + +/** + * This annotation is used to annotate a value that should only contain nonnegative values. + *

+ * 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 { + + public When forConstantValue(Nonnegative annotation, Object v) { + if (!(v instanceof Number)) + return When.NEVER; + boolean isNegative; + Number value = (Number) v; + if (value instanceof Long) + isNegative = value.longValue() < 0; + else if (value instanceof Double) + isNegative = value.doubleValue() < 0; + else if (value instanceof Float) + isNegative = value.floatValue() < 0; + else + isNegative = value.intValue() < 0; + + if (isNegative) + return When.NEVER; + else + return When.ALWAYS; + + } + } +} diff --git a/src/main/java/javax/annotation/Nonnull.java b/src/main/java/javax/annotation/Nonnull.java new file mode 100644 index 0000000..acaa4af --- /dev/null +++ b/src/main/java/javax/annotation/Nonnull.java @@ -0,0 +1,32 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifier; +import javax.annotation.meta.TypeQualifierValidator; +import javax.annotation.meta.When; + +/** + * The annotated element must not be null. + *

+ * Annotated fields must not be null after construction has completed. + *

+ * When this annotation is applied to a method it applies to the method return value. + */ +@Documented +@TypeQualifier +@Retention(RetentionPolicy.RUNTIME) +public @interface Nonnull { + When when() default When.ALWAYS; + + class Checker implements TypeQualifierValidator { + + public When forConstantValue(Nonnull qualifierArgument, Object value) { + if (value == null) + return When.NEVER; + return When.ALWAYS; + } + } +} diff --git a/src/main/java/javax/annotation/Nullable.java b/src/main/java/javax/annotation/Nullable.java new file mode 100644 index 0000000..f9c8772 --- /dev/null +++ b/src/main/java/javax/annotation/Nullable.java @@ -0,0 +1,31 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +/** + * The annotated element could be null under some circumstances. + *

+ * In general, this means developers will have to read the documentation to + * determine when a null value is acceptable and whether it is necessary to + * check for a null value. + *

+ * This annotation is useful mostly for overriding a {@link Nonnull} annotation. + * Static analysis tools should generally treat the annotated items as though they + * had no annotation, unless they are configured to minimize false negatives. + * Use {@link CheckForNull} to indicate that the element value should always be checked + * for a null value. + *

+ * When this annotation is applied to a method it applies to the method return value. + */ +@Documented +@TypeQualifierNickname +@Nonnull(when = When.UNKNOWN) +@Retention(RetentionPolicy.RUNTIME) +public @interface Nullable { + +} diff --git a/src/main/java/javax/annotation/OverridingMethodsMustInvokeSuper.java b/src/main/java/javax/annotation/OverridingMethodsMustInvokeSuper.java new file mode 100644 index 0000000..9b7515f --- /dev/null +++ b/src/main/java/javax/annotation/OverridingMethodsMustInvokeSuper.java @@ -0,0 +1,21 @@ +package javax.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; + +/** + * When this annotation is applied to a method, it indicates that if this method + * is overridden in a subclass, the overriding method should invoke this method + * (through method invocation on super). + *

+ * An example of such method is {@link Object#finalize()}. + */ +@Documented +@Target( { ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface OverridingMethodsMustInvokeSuper { + +} diff --git a/src/main/java/javax/annotation/ParametersAreNonnullByDefault.java b/src/main/java/javax/annotation/ParametersAreNonnullByDefault.java new file mode 100644 index 0000000..a2402b5 --- /dev/null +++ b/src/main/java/javax/annotation/ParametersAreNonnullByDefault.java @@ -0,0 +1,28 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.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: + *

+ * + * @see Nonnull + */ +@Documented +@Nonnull +@TypeQualifierDefault(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface ParametersAreNonnullByDefault { +} diff --git a/src/main/java/javax/annotation/ParametersAreNullableByDefault.java b/src/main/java/javax/annotation/ParametersAreNullableByDefault.java new file mode 100644 index 0000000..959cee2 --- /dev/null +++ b/src/main/java/javax/annotation/ParametersAreNullableByDefault.java @@ -0,0 +1,30 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.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: + * + *

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/src/main/java/javax/annotation/PropertyKey.java b/src/main/java/javax/annotation/PropertyKey.java new file mode 100644 index 0000000..780782d --- /dev/null +++ b/src/main/java/javax/annotation/PropertyKey.java @@ -0,0 +1,15 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifier; +import javax.annotation.meta.When; + +@Documented +@TypeQualifier +@Retention(RetentionPolicy.RUNTIME) +public @interface PropertyKey { + When when() default When.ALWAYS; +} diff --git a/src/main/java/javax/annotation/RegEx.java b/src/main/java/javax/annotation/RegEx.java new file mode 100644 index 0000000..ba80cf9 --- /dev/null +++ b/src/main/java/javax/annotation/RegEx.java @@ -0,0 +1,43 @@ +package javax.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 javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.TypeQualifierValidator; +import javax.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 { + + public When forConstantValue(RegEx annotation, Object value) { + if (!(value instanceof String)) + return When.NEVER; + + try { + Pattern.compile((String) value); + } catch (PatternSyntaxException e) { + return When.NEVER; + } + return When.ALWAYS; + + } + + } + +} diff --git a/src/main/java/javax/annotation/Signed.java b/src/main/java/javax/annotation/Signed.java new file mode 100644 index 0000000..d8cf61c --- /dev/null +++ b/src/main/java/javax/annotation/Signed.java @@ -0,0 +1,19 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.annotation.meta.When; + +/** + * Used to annotate a value of unknown sign. + */ +@Documented +@TypeQualifierNickname +@Nonnegative(when = When.UNKNOWN) +@Retention(RetentionPolicy.RUNTIME) +public @interface Signed { + +} diff --git a/src/main/java/javax/annotation/Syntax.java b/src/main/java/javax/annotation/Syntax.java new file mode 100644 index 0000000..f784ccc --- /dev/null +++ b/src/main/java/javax/annotation/Syntax.java @@ -0,0 +1,45 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifier; +import javax.annotation.meta.When; + +/** + * This annotation a value that is of a particular syntax, such as Java syntax + * or regular expression syntax. This can be used to provide syntax checking of + * constant values at compile time, run time checking at runtime, and can assist + * IDEs in deciding how to interpret String constants (e.g., should a + * refactoring that renames method {@code x()} to {@code y()} + * update the String constant {@code "x()"}). + */ +@Documented +@TypeQualifier(applicableTo = CharSequence.class) +@Retention(RetentionPolicy.RUNTIME) +public @interface Syntax { + /** + * Value indicating the particular syntax denoted by this annotation. + * Different tools will recognize different syntaxes, but some proposed + * canonical values are: + *

+ *

+ * 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/src/main/java/javax/annotation/Tainted.java b/src/main/java/javax/annotation/Tainted.java new file mode 100644 index 0000000..aec51de --- /dev/null +++ b/src/main/java/javax/annotation/Tainted.java @@ -0,0 +1,27 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifierNickname; +import javax.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/src/main/java/javax/annotation/Untainted.java b/src/main/java/javax/annotation/Untainted.java new file mode 100644 index 0000000..3a8b563 --- /dev/null +++ b/src/main/java/javax/annotation/Untainted.java @@ -0,0 +1,26 @@ +package javax.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import javax.annotation.meta.TypeQualifier; +import javax.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/src/main/java/javax/annotation/WillClose.java b/src/main/java/javax/annotation/WillClose.java new file mode 100644 index 0000000..82344f1 --- /dev/null +++ b/src/main/java/javax/annotation/WillClose.java @@ -0,0 +1,18 @@ +package javax.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/src/main/java/javax/annotation/WillCloseWhenClosed.java b/src/main/java/javax/annotation/WillCloseWhenClosed.java new file mode 100644 index 0000000..d67ae4f --- /dev/null +++ b/src/main/java/javax/annotation/WillCloseWhenClosed.java @@ -0,0 +1,18 @@ +package javax.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/src/main/java/javax/annotation/WillNotClose.java b/src/main/java/javax/annotation/WillNotClose.java new file mode 100644 index 0000000..4145fab --- /dev/null +++ b/src/main/java/javax/annotation/WillNotClose.java @@ -0,0 +1,18 @@ +package javax.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/src/main/java/javax/annotation/concurrent/GuardedBy.java b/src/main/java/javax/annotation/concurrent/GuardedBy.java new file mode 100644 index 0000000..0180f64 --- /dev/null +++ b/src/main/java/javax/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 javax.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: + *

+ */ +@Target( { ElementType.FIELD, ElementType.METHOD }) +@Retention(RetentionPolicy.CLASS) +public @interface GuardedBy { + String value(); +} diff --git a/src/main/java/javax/annotation/concurrent/Immutable.java b/src/main/java/javax/annotation/concurrent/Immutable.java new file mode 100644 index 0000000..72bd98b --- /dev/null +++ b/src/main/java/javax/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 javax.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. + *

+ * 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/src/main/java/javax/annotation/concurrent/NotThreadSafe.java b/src/main/java/javax/annotation/concurrent/NotThreadSafe.java new file mode 100644 index 0000000..596f0b2 --- /dev/null +++ b/src/main/java/javax/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 javax.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/src/main/java/javax/annotation/concurrent/ThreadSafe.java b/src/main/java/javax/annotation/concurrent/ThreadSafe.java new file mode 100644 index 0000000..36d7436 --- /dev/null +++ b/src/main/java/javax/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 javax.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/src/main/java/javax/annotation/meta/Exclusive.java b/src/main/java/javax/annotation/meta/Exclusive.java new file mode 100644 index 0000000..322a3ea --- /dev/null +++ b/src/main/java/javax/annotation/meta/Exclusive.java @@ -0,0 +1,27 @@ +package javax.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)}. + * + *

+ * @TypeQualifier @interface Foo {
+ *     @Exclusive int value();
+ * }
+ * 
+ * + */ + +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface Exclusive { + +} diff --git a/src/main/java/javax/annotation/meta/Exhaustive.java b/src/main/java/javax/annotation/meta/Exhaustive.java new file mode 100644 index 0000000..4ae7451 --- /dev/null +++ b/src/main/java/javax/annotation/meta/Exhaustive.java @@ -0,0 +1,35 @@ +package javax.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. + * + *

+ * 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)} + * + *

+ * @TypeQualifier  @interface Foo {
+ *     enum Color {RED, BLUE, GREEN};
+ *     @Exhaustive Color value();
+ * }
+ * 
+ */ + +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface Exhaustive { + +} diff --git a/src/main/java/javax/annotation/meta/TypeQualifier.java b/src/main/java/javax/annotation/meta/TypeQualifier.java new file mode 100644 index 0000000..bdaea3a --- /dev/null +++ b/src/main/java/javax/annotation/meta/TypeQualifier.java @@ -0,0 +1,29 @@ +package javax.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/src/main/java/javax/annotation/meta/TypeQualifierDefault.java b/src/main/java/javax/annotation/meta/TypeQualifierDefault.java new file mode 100644 index 0000000..0c8bd52 --- /dev/null +++ b/src/main/java/javax/annotation/meta/TypeQualifierDefault.java @@ -0,0 +1,20 @@ +package javax.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/src/main/java/javax/annotation/meta/TypeQualifierNickname.java b/src/main/java/javax/annotation/meta/TypeQualifierNickname.java new file mode 100644 index 0000000..ff1528a --- /dev/null +++ b/src/main/java/javax/annotation/meta/TypeQualifierNickname.java @@ -0,0 +1,29 @@ +package javax.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. + * + *

+ * Thus, you might define a qualifier SocialSecurityNumber as follows: + *

+ * + *
+ * @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/src/main/java/javax/annotation/meta/TypeQualifierValidator.java b/src/main/java/javax/annotation/meta/TypeQualifierValidator.java new file mode 100644 index 0000000..8053011 --- /dev/null +++ b/src/main/java/javax/annotation/meta/TypeQualifierValidator.java @@ -0,0 +1,21 @@ +package javax.annotation.meta; + +import java.lang.annotation.Annotation; + +import javax.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/src/main/java/javax/annotation/meta/When.java b/src/main/java/javax/annotation/meta/When.java new file mode 100644 index 0000000..ec8a1bc --- /dev/null +++ b/src/main/java/javax/annotation/meta/When.java @@ -0,0 +1,23 @@ +package javax.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; + +}