aboutsummaryrefslogtreecommitdiffstats
path: root/docs/adk15notebook/annotations.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/adk15notebook/annotations.xml')
-rw-r--r--docs/adk15notebook/annotations.xml1420
1 files changed, 1420 insertions, 0 deletions
diff --git a/docs/adk15notebook/annotations.xml b/docs/adk15notebook/annotations.xml
new file mode 100644
index 000000000..f9be0d0da
--- /dev/null
+++ b/docs/adk15notebook/annotations.xml
@@ -0,0 +1,1420 @@
+<chapter id="annotations" xreflabel="Annotations">
+
+ <title>Annotations</title>
+
+ <sect1 id="annotations-inJava5">
+ <title>Annotations in Java 5</title>
+
+ <para>
+ This section provides the essential information about annotations in
+ Java 5 needed to understand how annotations are treated in AspectJ 5.
+ For a full introduction to annotations in Java, please see the
+ documentation for the Java 5 SDK.
+ </para>
+
+ <sect2 id="using-annotations" xreflabel="using-annotations">
+ <title>Using Annotations</title>
+
+ <para>
+ Java 5 introduces <emphasis>annotation types</emphasis> which can
+ be used to express metadata relating to program members in the
+ form of <emphasis>annotations</emphasis>. Annotations in Java 5
+ can be applied to package and type declarations (classes,
+ interfaces, enums, and annotations), constructors, methods,
+ fields, parameters, and variables. Annotations are specified in the
+ program source by using the <literal>@</literal> symbol. For example,
+ the following piece of code uses the <literal>@Deprecated</literal>
+ annotation to indicate that the <literal>obsoleteMethod()</literal>
+ has been deprecated:
+ </para>
+
+ <programlisting><![CDATA[
+@Deprecated
+public void obsoleteMethod() { ... }
+]]> </programlisting>
+
+ <para>
+ Annotations may be <emphasis>marker annotations</emphasis>,
+ <emphasis>single-valued annotations</emphasis>, or
+ <emphasis>multi-valued annotations</emphasis>.
+ Annotation types with no members or that provide default values
+ for all members may be used simply as marker annotations, as in
+ the deprecation example above. Single-value annotation types have
+ a single member, and the annotation may be written in one of
+ two equivalent forms:
+ </para>
+
+ <programlisting><![CDATA[
+@SuppressWarnings({"unchecked"})
+public void someMethod() {...}
+]]> </programlisting>
+
+ <para>
+ or
+ </para>
+
+ <programlisting><![CDATA[
+@SuppressWarnings(value={"unchecked"})
+public void someMethod() {...}
+]]> </programlisting>
+
+ <para>
+ Multi-value annotations must use the <literal>member-name=value
+ </literal> syntax to specify annotation values. For example:
+ </para>
+
+ <programlisting><![CDATA[
+@Authenticated(role="supervisor",clearanceLevel=5)
+public void someMethod() {...}
+]]> </programlisting>
+
+ </sect2>
+
+ <sect2 id="retention-policies" xreflabel="retention-policies">
+ <title>Retention Policies</title>
+
+ <para>
+ Annotations can have one of three retention policies:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>Source-file retention</term>
+ <listitem>
+ <para>
+ Annotations with source-file retention are read by the
+ compiler during the compilation process, but are not
+ rendered in the generated <literal>.class</literal> files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Class-file retention</term>
+ <listitem>
+ <para>
+ This is the default retention policy. Annotations
+ with class-file retention are read by the compiler
+ and also retained in the generated <literal>
+ .class</literal> files.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>Runtime retention</term>
+ <listitem>
+ <para>
+ Annotations with runtime retention are read by the
+ compiler, retained in the generated <literal>
+ .class</literal> files, and also made available
+ at runtime.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>Local variable annotations are not retained in class files (or at runtime)
+ regardless of the retention policy set on the annotation type. See JLS 9.6.1.2.</para>
+ </sect2>
+
+ <sect2 id="accessing-annotations-at-runtime" xreflabel="accessing-annotations-at-runtime">
+ <title>Accessing Annotations at Runtime</title>
+
+ <para>
+ Java 5 supports a new interface,
+ <literal>java.lang.reflect.AnnotatedElement</literal>, that is
+ implemented by the reflection classes in Java (<literal>Class</literal>,
+ <literal>Constructor</literal>,
+ <literal>Field</literal>, <literal>Method</literal>, and
+ <literal>Package</literal>). This interface gives you access
+ to annotations <emphasis>that have runtime retention</emphasis> via
+ the <literal>getAnnotation</literal>, <literal>getAnnotations</literal>,
+ and <literal>isAnnotationPresent</literal>. Because annotation types are
+ just regular Java classes, the annotations returned by these methods
+ can be queried just like any regular Java object.
+ </para>
+
+ </sect2>
+
+ <sect2 id="annotation-inheritance" xreflabel="annotation-inheritance">
+ <title>Annotation Inheritance</title>
+
+ <para>
+ It is important to understand the rules relating to inheritance of
+ annotations, as these have a bearing on join point matching
+ based on the presence or absence of annotations.
+ </para>
+
+ <para>
+ By default annotations are <emphasis>not</emphasis> inherited. Given
+ the following program
+ </para>
+
+ <programlisting><![CDATA[
+@MyAnnotation
+class Super {
+ @Oneway public void foo() {}
+}
+
+class Sub extends Super {
+ public void foo() {}
+}
+]]> </programlisting>
+
+ <para>
+ Then <literal>Sub</literal> <emphasis>does not</emphasis> have
+ the <literal>MyAnnotation</literal> annotation, and
+ <literal>Sub.foo()</literal> is not an <literal>@Oneway</literal>
+ method, despite the fact that it overrides
+ <literal>Super.foo()</literal> which is.
+ </para>
+
+ <para>
+ If an annotation type has the meta-annotation <literal>@Inherited</literal>
+ then an annotation of that type on a <emphasis>class</emphasis> will cause
+ the annotation to be inherited by sub-classes. So, in the example
+ above, if the <literal>MyAnnotation</literal> type had the
+ <literal>@Inherited</literal> attribute, then <literal>Sub</literal>
+ would have the <literal>MyAnnotation</literal> annotation.
+ </para>
+
+ <para>
+ <literal>@Inherited</literal> annotations are not inherited when used to
+ annotate anything other than a type. A type
+ that implements one or more interfaces never inherits any annotations from
+ the interfaces it implements.
+ </para>
+
+ </sect2>
+ </sect1>
+
+ <!-- ============================== -->
+
+ <sect1 id="annotations-aspectmembers">
+ <title>Annotating Aspects</title>
+
+ <para>
+ AspectJ 5 supports annotations on aspects, and on method, field,
+ constructor, advice, and inter-type declarations within aspects.
+ Method and advice parameters may also be annotated.
+ Annotations are not permitted on pointcut declarations or on
+ <literal>declare</literal> statements.
+ </para>
+
+ <para>
+ The following example illustrates the use of annotations in aspects:
+ </para>
+
+
+ <programlisting><![CDATA[
+@AspectAnnotation
+public abstract aspect ObserverProtocol {
+
+ @InterfaceAnnotation
+ interface Observer {}
+
+ @InterfaceAnnotation
+ interface Subject {}
+
+ @ITDFieldAnnotation
+ private List<Observer> Subject.observers;
+
+ @ITDMethodAnnotation
+ public void Subject.addObserver(Observer o) {
+ observers.add(o);
+ }
+
+ @ITDMethodAnnotation
+ public void Subject.removeObserver(Observer o) {
+ observers.remove(o);
+ }
+
+ @MethodAnnotation
+ private void notifyObservers(Subject subject) {
+ for(Observer o : subject.observers)
+ notifyObserver(o,subject);
+ }
+
+ /**
+ * Delegate to concrete sub-aspect the actual form of
+ * notification for a given type of Observer.
+ */
+ @MethodAnnotation
+ protected abstract void notifyObserver(Observer o, Subject s);
+
+ /* no annotations on pointcuts */
+ protected abstract pointcut observedEvent(Subject subject);
+
+ @AdviceAnnotation
+ after(Subject subject) returning : observedEvent(subject) {
+ notifyObservers(subject);
+ }
+}
+]]></programlisting>
+
+ <para>
+ An annotation on an aspect will be inherited by sub-aspects, iff it has
+ the <literal>@Inherited</literal> meta-annotation.
+ </para>
+
+ <para>
+ AspectJ 5 supports a new XLint warning, "the pointcut associated with this
+ advice does not match any join points". The warning is enabled by default and
+ will be emitted by the compiler if the pointcut expression associated with an
+ advice statement can be statically determined to not match any join points. The
+ warning can be suppressed for an individual advice statement by using the
+ <literal>@SuppressAjWarnings({"adviceDidNotMatch"})</literal> annotation. This works in
+ the same way as the Java 5 SuppressWarnings annotation (See JLS 9.6.1.5), but has class file
+ retention.
+ </para>
+
+ <programlisting><![CDATA[
+import org.aspectj.lang.annotation.SuppressAjWarnings;
+
+public aspect AnAspect {
+
+ pointcut anInterfaceOperation() : execution(* AnInterface.*(..));
+
+
+ @SuppressAjWarnings // may not match if there are no implementers of the interface...
+ before() : anInterfaceOperation() {
+ // do something...
+ }
+
+ @SuppressAjWarnings("adviceDidNotMatch") // alternate form
+ after() returning : anInterfaceOperation() {
+ // do something...
+ }
+}
+]]></programlisting>
+
+
+ </sect1>
+
+ <!-- ============================== -->
+
+ <sect1 id="annotations-pointcuts-and-advice">
+ <title>Join Point Matching based on Annotations</title>
+
+ <para>
+ This section discusses changes to type pattern and signature pattern matching in
+ AspectJ 5 that support matching join points based on the presence or absence of
+ annotations. We then discuss means of exposing annotation values within the body
+ of advice.
+ </para>
+
+ <sect2 id="annotation-patterns" xreflabel="annotation-patterns">
+ <title>Annotation Patterns</title>
+
+ <para>
+ For any kind of annotated element (type, method, constructor, package, etc.),
+ an annotation pattern can be used to match against the set of annotations
+ on the annotated element.An annotation pattern element has one of two basic
+ forms:
+ </para>
+
+ <itemizedlist>
+ <listitem>@&lt;qualified-name&gt;, for example, @Foo, or
+ @org.xyz.Foo.</listitem>
+ <listitem>@(&lt;type-pattern&gt;), for example, @(org.xyz..*), or
+ @(Foo || Boo)</listitem>
+ </itemizedlist>
+
+ <para>These simple elements may be negated using <literal>!</literal>, and
+ combined by simple concatentation. The pattern <literal>@Foo @Boo</literal>
+ matches an annotated element that has both an annotation of type <literal>Foo</literal>
+ and an annotation of type <literal>Boo</literal>.</para>
+
+ <para>Some examples of annotation patterns follow:</para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>@Immutable</term>
+ <listitem>
+ <para>
+ Matches any annotated element which has an annotation of
+ type <literal>Immutable</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>!@Persistent</term>
+ <listitem>
+ <para>
+ Matches any annotated element which does not have an annotation of
+ type <literal>Persistent</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@Foo @Goo</term>
+ <listitem>
+ <para>
+ Matches any annotated element which has both an annotation of type <literal>Foo</literal> and
+ an annotation of type <literal>Goo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@(Foo || Goo)</term>
+ <listitem>
+ <para>
+ Matches any annotated element which has either an annotation of a type matching
+ the type pattern <literal>(Foo || Goo)</literal>.
+ In other words, an annotated element with either an
+ annotation of type <literal>Foo</literal> or
+ an annotation of type <literal>Goo</literal> (or both). (The parenthesis are required in this example).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@(org.xyz..*)</term>
+ <listitem>
+ <para>
+ Matches any annotated element which has either an annotation of a type matching
+ the type pattern <literal>(org.xyz..*)</literal>.
+ In other words, an annotated element with an annotation that is declared in the
+ org.xyz package or a sub-package. (The parenthesis are required in this example).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="type-patterns" xreflabel="type-patterns">
+ <title>Type Patterns</title>
+
+ <para>AspectJ 1.5 extends type patterns to allow an optional <literal>AnnotationPattern</literal>
+ prefix.</para>
+
+ <programlisting><![CDATA[
+TypePattern := SimpleTypePattern |
+ '!' TypePattern |
+ '(' AnnotationPattern? TypePattern ')'
+ TypePattern '&&' TypePattern |
+ TypePattern '||' TypePattern
+
+SimpleTypePattern := DottedNamePattern '+'? '[]'*
+
+DottedNamePattern := FullyQualifiedName RestOfNamePattern? |
+ '*' NotStarNamePattern?
+
+RestOfNamePattern := '..' DottedNamePattern |
+ '*' NotStarNamePattern?
+
+NotStarNamePattern := FullyQualifiedName RestOfNamePattern? |
+ '..' DottedNamePattern
+
+FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*
+]]></programlisting>
+
+ <para>Note that in most cases when annotations are used as part of a type pattern,
+ the parenthesis are required (as in <literal>(@Foo Hello+)</literal>). In
+ some cases (such as a type pattern used within a <literal>within</literal> or
+ <literal>handler</literal>
+ pointcut expression), the parenthesis are optional:</para>
+
+ <programlisting><![CDATA[
+OptionalParensTypePattern := AnnotationPattern? TypePattern
+]]> </programlisting>
+
+ <para>
+ The following examples illustrate the use of annotations in type
+ patterns:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>(@Immutable *)</term>
+ <listitem>
+ <para>
+ Matches any type with an <literal>@Immutable</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>(!@Immutable *)</term>
+ <listitem>
+ <para>
+ Matches any type which does not have an <literal>@Immutable</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term> (@Immutable (org.xyz.* || org.abc.*))</term>
+ <listitem>
+ <para>
+ Matches any type in the <literal>org.xyz</literal> or <literal>org.abc</literal>
+ packages with the <literal>@Immutable</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>((@Immutable Foo+) || Goo)</term>
+ <listitem>
+ <para>
+ Matches a type <literal>Foo</literal> or any of its subtypes, which have the <literal>@Immutable</literal>
+ annotation, or a type <literal>Goo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>((@(Immutable || NonPersistent) org.xyz..*)</term>
+ <listitem>
+ <para>
+ Matches any type in a package beginning with the prefix <literal>org.xyz</literal>,
+ which has either the <literal>@Immutable</literal> annotation or the
+ <literal>@NonPersistent</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>(@Immutable @NonPersistent org.xyz..*)</term>
+ <listitem>
+ <para>
+ Matches any type in a package beginning with the prefix <literal>org.xyz</literal>,
+ which has both an <literal>@Immutable</literal> annotation and an
+ <literal>@NonPersistent</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term> (@(@Inherited *) org.xyz..*)</term>
+ <listitem>
+ <para>
+ Matches any type in a package beginning with the prefix <literal>org.xyz</literal>,
+ which has an inheritable annotation. The annotation pattern
+ <literal>@(@Inherited *)</literal> matches any annotation of a type matching the
+ type pattern <literal>@Inherited *</literal>, which in turn matches any type with the
+ <literal>@Inherited</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="signaturePatterns" xreflabel="Signature Patterns">
+ <title>Signature Patterns</title>
+
+ <sect3 id="fieldPatterns" xreflabel="Field Patterns">
+ <title>Field Patterns</title>
+
+ <para>A <literal>FieldPattern</literal> can optionally specify an annotation-matching
+ pattern as the first element:</para>
+
+ <programlisting><![CDATA[
+FieldPattern :=
+ AnnotationPattern? FieldModifiersPattern?
+ TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
+
+FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
+
+FieldModifier := 'public' | 'private' | 'protected' | 'static' |
+ 'transient' | 'final'
+
+DotOrDotDot := '.' | '..'
+
+SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
+]]></programlisting>
+
+ <para>
+ If present, the <literal>AnnotationPattern</literal> restricts matches to fields with
+ annotations that match the pattern. For example:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>@SensitiveData * *</term>
+ <listitem>
+ <para>
+ Matches a field of any type and any name, that has an annotation of
+ type <literal>@SensitiveData</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@SensitiveData List org.xyz..*.*</term>
+ <listitem>
+ <para>
+ Matches a member field of a type in a package with prefix <literal>org.xzy</literal>,
+ where the field is of type <literal>List</literal>, and has an annotation of type
+ <literal>@SensitiveData</literal>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>(@SensitiveData *) org.xyz..*.*</term>
+ <listitem>
+ <para>
+ Matches a member field of a type in a package with prefix <literal>org.xzy</literal>,
+ where the field is of a type which has a <literal>@SensitiveData</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@Foo (@Goo *) (@Hoo *).*</term>
+ <listitem>
+ <para>
+ Matches a field with an annotation <literal>@Foo</literal>, of a type with an
+ annotation <literal>@Goo</literal>, declared in a type with annotation
+ <literal>@Hoo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@Persisted @Classified * *</term>
+ <listitem>
+ <para>
+ Matches a field with an annotation <literal>@Persisted</literal> and
+ an annotation <literal>@Classified</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect3>
+
+ <sect3 id="methodPatterns" xreflabel="Method Patterns">
+ <title>Method and Constructor Patterns</title>
+
+ <para>A <literal>MethodPattern</literal> can optionally specify an annotation-matching
+ pattern as the first element.</para>
+
+<programlisting><![CDATA[
+MethodPattern :=
+ AnnotationPattern? MethodModifiersPattern? TypePattern
+ (TypePattern DotOrDotDot)? SimpleNamePattern
+ '(' FormalsPattern ')'ThrowsPattern?
+
+MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*
+
+MethodModifier := 'public' | 'private' | 'protected' | 'static' |
+ 'synchronized' | 'final'
+
+FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* |
+ OptionalParensTypePattern (',' FormalsPattern)* |
+ TypePattern '...'
+
+FormalsPatternAfterDotDot :=
+ OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
+ TypePattern '...'
+
+ThrowsPattern := 'throws' TypePatternList
+
+TypePatternList := TypePattern (',' TypePattern)*
+]]></programlisting>
+
+ <para>A <literal>ConstructorPattern</literal> has the form</para>
+
+ <programlisting><![CDATA[
+ConstructorPattern :=
+ AnnotationPattern? ConstructorModifiersPattern?
+ (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
+ ThrowsPattern?
+
+ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
+
+ConstructorModifier := 'public' | 'private' | 'protected'
+]]></programlisting>
+
+ <para>
+ The optional <literal>AnnotationPattern</literal> at the beginning of a
+ method or constructor pattern restricts matches to methods/constructors with
+ annotations that match the pattern. For example:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>@Oneway * *(..)</term>
+ <listitem>
+ <para>
+ Matches a method with any return type and any name, that has an annotation of
+ type <literal>@Oneway</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>@Transaction * (@Persistent org.xyz..*).*(..)</term>
+ <listitem>
+ <para>
+ Matches a method with the <literal>@Transaction</literal> annotation,
+ declared in a type with the <literal>@Persistent</literal> annotation, and
+ in a package beginning with the <literal>org.xyz</literal> prefix.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>* *.*(@Immutable *,..)</term>
+ <listitem>
+ <para>
+ Matches any method taking at least one parameter, where the parameter
+ type has an annotation <literal>@Immutable</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2 id="example-pointcuts" xreflabel="example-pointcuts">
+ <title>Example Pointcuts</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>within(@Secure *)</term>
+ <listitem>
+ <para>
+ Matches any join point where the code executing is declared in a
+ type with an <literal>@Secure</literal>
+ annotation. The format of the <literal>within</literal> pointcut designator
+ in AspectJ 5 is <literal>'within' '(' OptionalParensTypePattern ')'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>staticinitialization(@Persistent *)</term>
+ <listitem>
+ <para>
+ Matches the staticinitialization join point of any type with the
+ <literal>@Persistent</literal> annotation. The format of the
+ <literal>staticinitialization</literal> pointcut designator
+ in AspectJ 5 is <literal>'staticinitialization' '(' OptionalParensTypePattern ')'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>call(@Oneway * *(..))</term>
+ <listitem>
+ <para>
+ Matches a call to a method with a <literal>@Oneway</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>execution(public (@Immutable *) org.xyz..*.*(..))</term>
+ <listitem>
+ <para>
+ The execution of any public method in a package with prefix
+ <literal>org.xyz</literal>, where the method returns an
+ immutable result.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>set(@Cachable * *)</term>
+ <listitem>
+ <para>
+ Matches the set of any cachable field.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>handler(!@Catastrophic *)</term>
+ <listitem>
+ <para>
+ Matches the handler join point for the handling of any exception that is
+ not <literal>Catastrophic</literal>. The format of the <literal>handler</literal>
+ pointcut designator in AspectJ 5 is <literal>'handler' '(' OptionalParensTypePattern ')'</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ <sect2 id="runtime-type-matching-and-context-exposure" xreflabel="runtime-type-matching-and-context-exposure">
+ <title>Runtime type matching and context exposure</title>
+
+ <para>AspectJ 5 supports a set of "@" pointcut designators which
+ can be used both to match based on the presence of an annotation at
+ runtime, and to expose the annotation value as context in a pointcut or
+ advice definition. These designators are <literal>@args, @this, @target,
+ @within, @withincode</literal>, and <literal>@annotation</literal>
+ </para>
+
+ <para>It is a compilation error to attempt to match on an annotation type
+ that does not have runtime retention using <literal>@this, @target</literal>
+ or <literal>@args</literal>. It is a compilation error to attempt to use
+ any of these designators to expose an annotation value that does not
+ have runtime retention.</para>
+
+ <para>
+ The <literal>this()</literal>, <literal>target()</literal>, and
+ <literal>args()</literal> pointcut designators allow matching based
+ on the runtime type of an object, as opposed to the statically
+ declared type. In AspectJ 5, these designators are supplemented
+ with three new designators : <literal>@this()</literal> (read, "this
+ annotation"), <literal>@target()</literal>, and <literal>@args()</literal>.
+ </para>
+
+ <para>
+ Like their counterparts, these pointcut designators can be used
+ both for join point matching, and to expose context. The format of
+ these new designators is:
+ </para>
+
+ <programlisting><![CDATA[
+AtThis := '@this' '(' AnnotationOrIdentifer ')'
+
+AtTarget := '@target' '(' AnnotationOrIdentifier ')'
+
+AnnotationOrIdentifier := FullyQualifiedName | Identifier
+
+AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
+
+AnnotationsOrIdentifiersPattern :=
+ '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
+ '*' (',' AnnotationsOrIdentifiersPattern)*
+
+AnnotationsOrIdentifiersPatternAfterDotDot :=
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
+ '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
+]]></programlisting>
+
+ <para>
+ The forms of <literal>@this()</literal> and <literal>@target()</literal> that
+ take a single annotation name are analogous to their counterparts that take
+ a single type name. They match at join points where the object bound to
+ <literal>this</literal> (or <literal>target</literal>, respectively) has an
+ annotation of the specified type. For example:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>@this(Foo)</term>
+ <listitem>
+ <para>
+ Matches any join point where the object currently bound to 'this'
+ has an annotation of type <literal>Foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>call(* *(..)) &amp;&amp; @target(Classified)</term>
+ <listitem>
+ <para>
+ Matches a call to any object where the target of the call has
+ a <literal>@Classified</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ Annotations can be exposed as context in the body of advice by
+ using the forms of <literal>@this(), @target()</literal> and
+ <literal>@args()</literal> that use bound variables in the place
+ of annotation names. For example:
+ </para>
+
+ <programlisting><![CDATA[
+pointcut callToClassifiedObject(Classified classificationInfo) :
+ call(* *(..)) && @target(classificationInfo);
+
+pointcut txRequiredMethod(Tx transactionAnnotation) :
+ execution(* *(..)) && @this(transactionAnnotation)
+ && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
+]]></programlisting>
+
+ <para>
+ The <literal>@args</literal> pointcut designator behaves as its <literal>args</literal>
+ counterpart, matching join points based on number and position of arguments, and
+ supporting the <literal>*</literal> wildcard and at most one <literal>..</literal>
+ wildcard. An annotation at a given position in an <literal>@args</literal> expression
+ indicates that the runtime type of the argument in that position at a join point must
+ have an annotation of the indicated type. For example:
+ </para>
+
+ <programlisting><![CDATA[
+/**
+ * matches any join point with at least one argument, and where the
+ * type of the first argument has the @Classified annotation
+ */
+pointcut classifiedArgument() : @args(Classified,..);
+
+/**
+ * matches any join point with three arguments, where the third
+ * argument has an annotation of type @Untrusted.
+ */
+pointcut untrustedData(Untrusted untrustedDataSource) :
+ @args(*,*,untrustedDataSource);
+]]></programlisting>
+
+ <para>In addition to accessing annotation information at runtime through context binding,
+ access to <literal>AnnotatedElement</literal> information is also available
+ reflectively with the body of advice through the <literal>thisJoinPoint</literal>,
+ <literal>thisJoinPointStaticPart</literal>, and
+ <literal>thisEnclosingJoinPointStaticPart</literal> variables. To access
+ annotations on the arguments, or object bound to this or target at a join
+ point you can use the following code fragments:</para>
+
+ <programlisting><![CDATA[
+Annotation[] thisAnnotations = thisJoinPoint.getThis().getClass().getAnnotations();
+Annotation[] targetAnnotations = thisJoinPoint.getTarget().getClass().getAnnotations();
+Annotation[] firstParamAnnotations = thisJoinPoint.getArgs()[0].getClass().getAnnotations();
+]]></programlisting>
+
+ <para>
+ The <literal>@within</literal> and <literal>@withincode</literal> pointcut designators
+ match any join point where the executing code is defined within a type (<literal>@within</literal>),
+ or a method/constructor (<literal>@withincode</literal>) that has an annotation of the specified
+ type. The form of these designators is:
+ </para>
+
+ <programlisting><![CDATA[
+AtWithin := '@within' '(' AnnotationOrIdentifier ')'
+AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
+]]></programlisting>
+
+ <para>Some examples of using these designators follow:</para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>@within(Foo)</term>
+ <listitem>
+ <para>
+ Matches any join point where the executing code is defined
+ within a type which has an annotation of type <literal>Foo</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>pointcut insideCriticalMethod(Critical c) :
+ @withincode(c);</term>
+ <listitem>
+ <para>
+ Matches any join point where the executing code is defined
+ in a method or constructor which has an annotation of type <literal>@Critical</literal>,
+ and exposes the value of the annotation in the parameter
+ <literal>c</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>The <literal>@annotation</literal> pointcut designator matches any
+ join point where the <emphasis>subject</emphasis> of the join point has
+ an annotation of the given type. Like the other @pcds, it can also be
+ used for context exposure.</para>
+
+ <programlisting><![CDATA[
+AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
+]]></programlisting>
+
+ <para>The subject of a join point is defined in the table in chapter one of
+ this guide.</para>
+
+ <para>
+ Access to annotation information on members at a matched join point is also available
+ through the <literal>getSignature</literal> method of the <literal>JoinPoint</literal>
+ and <literal>JoinPoint.StaticPart</literal> interfaces. The <literal>Signature</literal>
+ interfaces are extended with additional operations that provide access to the
+ <literal>java.lang.reflect</literal> <literal>Method, Field</literal> and
+ <literal>Constructor</literal> objects on which annnotations can be queried. The following fragment
+ illustrates an example use of this interface to access annotation information.
+ </para>
+
+ <programlisting><![CDATA[
+Signature sig = thisJoinPointStaticPart.getSignature();
+AnnotatedElement declaringTypeAnnotationInfo = sig.getDeclaringType();
+if (sig instanceof MethodSignature) {
+ // this must be a call or execution join point
+ Method method = ((MethodSignature)sig).getMethod();
+}
+]]></programlisting>
+
+ <para>
+ <emphasis>Note again that it would be nicer to add the method getAnnotationInfo
+ directly to MemberSignature, but this would once more couple the runtime library
+ to Java 5.</emphasis>
+ </para>
+
+ <para>
+ The <literal>@this,@target</literal> and <literal>@args</literal>
+ pointcut designators can only be used to match against annotations
+ that have runtime retention. The <literal>@within, @withincode</literal>
+ and <literal>@annotation</literal> pointcut designators can only be used
+ to match against annotations that have at least class-file retention, and
+ if used in the binding form the annotation must have runtime retention.
+ </para>
+
+ </sect2>
+
+
+ <sect2 id="package-and-parameter-annotations" xreflabel="package-and-parameter-annotations">
+ <title>Package and Parameter Annotations</title>
+
+ <para>
+ <emphasis>Matching on package annotations is not supported in AspectJ. Support for
+ this capability may be considered in a future release.</emphasis>
+
+ </para>
+
+ <para>
+ Parameter annotation matching is being added in AspectJ1.6.
+ Initially only matching is supported but binding will be
+ implemented at some point. Whether the annotation specified in a pointcut should be
+ considered to be an annotation on the parameter type or an annotation on the parameter
+ itself is determined through the use of parentheses around the parameter type.
+
+ Consider the following:
+ </para>
+
+
+ <programlisting><![CDATA[
+@SomeAnnotation
+class AnnotatedType {}
+
+class C {
+ public void foo(AnnotatedType a) {}
+ public void goo(@SomeAnnotation String s) {}
+}
+]]></programlisting>
+
+ <para>
+ The method foo has a parameter of an annotated type, and can be matched by this pointcut:
+ </para>
+ <programlisting><![CDATA[
+pointcut p(): execution(* *(@SomeAnnotation *));
+]]></programlisting>
+ <para>
+ When there is a single annotation specified like this, it is considered to be part of the type
+ pattern in the match against the parameter: 'a parameter of any type that has the annotation @SomeAnnotation'.
+ </para>
+ <para>
+ To match the parameter annotation case, the method goo, this is the pointcut:
+ </para>
+ <programlisting><![CDATA[
+pointcut p(): execution(* *(@SomeAnnotation (*)));
+]]></programlisting>
+ <para>
+ The use of parentheses around the wildcard is effectively indicating that the annotation should be considered
+ separately to the type pattern for the parameter type: 'a parameter of any type that has a parameter annotation of
+ @SomeAnnotation'.
+ </para>
+ <para>
+ To match when there is a parameter annotation and an annotation on the type as well:
+ </para>
+ <programlisting><![CDATA[
+pointcut p(): execution(* *(@SomeAnnotation (@SomeOtherAnnotation *)));
+]]></programlisting>
+ <para>
+ The parentheses are grouping @SomeOtherAnnotation with the * to form the type pattern for the parameter, then
+ the type @SomeAnnotation will be treated as a parameter annotation pattern.
+ </para>
+
+<!-- @withinpackage ??? -->
+
+<!--
+ <para>
+ Java 5 allows both packages and parameters to be annotated. To allow matching on package and parameter annotations,
+ AspectJ 5 introduces the <literal>@package</literal> and <literal>@parameters</literal> pointcut designators.
+ </para>
+
+ <programlisting><![CDATA[
+PackageAnnotationPointcut := '@package' '(' AnnotationPattern ')'
+]]></programlisting>
+
+ <para>The <literal>@package</literal> pointcut matches any join point
+ occuring within the scope of a package with
+ annotations matching the giving <literal>AnnotationPattern</literal>. For
+ example:
+ </para>
+
+ <programlisting><![CDATA[
+@package(@Model)
+]]></programlisting>
+
+ <para>
+ Matches any join point occuring within the scope of a package with the
+ <literal>@Model</literal> annotation.
+ </para>
+
+ <para>
+ <emphasis>
+ Note: we added @package as a result of a conscious decision not to allow the
+ specification of package annotation patterns within a general TypePattern. A
+ consequence of this decision is that we lose the ability to say the following
+ things: "a call to a method defined in a type in a package with annotations
+ matching..." ; "the set of a field defined in a type in a package with annotations
+ matching..." ; "the get of a field defined in a type in a package with annotations
+ matching...". As well as the package of the target at these join points, there is
+ also the package of the runtime type of the target (call/target difference). So
+ there are at least three possible sets of package annotations you could theoretically
+ want to match on at a call, get, or set join point. We have chosen to provide the
+ means to express the simplest of these, and could consider extending the language
+ to allow for the others in the future when we better understanding how users will
+ really use both package annotations and these features.
+ </emphasis>
+ </para>
+
+ <para>
+ The <literal>@parameter</literal> pointcut designator acts in a similar manner to
+ <literal>args</literal> in that it matches based on number and position of arguments
+ at a join point (and supports the same wildcard options of <literal>*</literal> and
+ <literal>..</literal>.
+ </para>
+
+ <programlisting><![CDATA[
+ParamsAnnotationPointcut := '@parameters' '(' ParamsAnnotationPattern ')'
+
+ParamsAnnotationPattern := AnnotationPattern (',' ParamsAnnotationPattern)? |
+ '*' (',' ParamsAnnotationPattern)? |
+ '..' (',' SingleParamsAnnotationPattern)*
+
+SingleParamsAnnotationPattern := AnnotationPattern (',' SingleParamsAnnotationPattern)? |
+ '*' (',' SingleParamsAnnotationPattern)?
+]]></programlisting>
+
+ <para>The <literal>*</literal> wildcard matches a single parameter regardless of its annotations.
+ The <literal>..</literal> wildcard matches zero or more parameters with any annotations. An
+ annotation pattern in a given parameter position matches a parameter in that position with annotations
+ matching the given annotation pattern. For example, the method signature</para>
+
+ <programlisting><![CDATA[
+public void foo(@Immutable int i, String s, @Cached Object o);
+]]></programlisting>
+
+ <para>Is matched by:</para>
+ <programlisting><![CDATA[@parameters(@Immutable, *, @Cached);]]></programlisting>
+ <para>and,</para>
+ <programlisting><![CDATA[@parameters(..,@Cached);]]></programlisting>
+ <para>and,</para>
+ <programlisting><![CDATA[@parameters(@Immutable, *, *);]]></programlisting>
+
+ <para>It is not matched by:</para>
+ <programlisting><![CDATA[@parameters(@Immutable, *);]]></programlisting>
+ <para>or,</para>
+ <programlisting><![CDATA[@parameters(*,@Immutable);]]></programlisting>
+ <para>or,</para>
+ <programlisting><![CDATA[@parameters(*, int, @Cached);]]></programlisting>
+
+ <para>
+ This last example will result in a compilation error since <literal>int</literal> is not a
+ valid annotation pattern.
+ </para>
+ -->
+
+ </sect2>
+
+ <sect2 id="annotation-inheritance-and-pointcut-matching" xreflabel="annotation-inheritance-and-pointcut-matching">
+ <title>Annotation Inheritance and pointcut matching</title>
+
+ <para>
+ According to the Java 5 specification, non-type annotations are not
+ inherited, and annotations on types are only inherited if they have the
+ <literal>@Inherited</literal> meta-annotation.
+
+ Given the following program:
+ </para>
+
+ <programlisting><![CDATA[
+class C1 {
+ @SomeAnnotation
+ public void aMethod() {...}
+}
+
+class C2 extends C1 {
+ public void aMethod() {...}
+}
+
+class Main {
+ public static void main(String[] args) {
+ C1 c1 = new C1();
+ C2 c2 = new C2();
+ c1.aMethod();
+ c2.aMethod();
+ }
+}
+
+aspect X {
+ pointcut annotatedC2MethodCall() :
+ call(@SomeAnnotation * C2.aMethod());
+
+ pointcut annotatedMethodCall() :
+ call(@SomeAnnotation * aMethod());
+}
+]]></programlisting>
+
+ <para>
+ The pointcut <literal>annotatedC2MethodCall</literal> will not match anything
+ since the definition of <literal>aMethod</literal> in <literal>C2</literal>
+ does not have the annotation.
+ </para>
+
+ <para>
+ The pointcut <literal>annotatedMethodCall</literal> matches
+ <literal>c1.aMethod()</literal> but not <literal>c2.aMethod()</literal>. The call
+ to <literal>c2.aMethod</literal> is not matched because join point matching for
+ modifiers (the visibility modifiers, annotations, and throws clause) is based on
+ the subject of the join point (the method actually being called).
+ </para>
+
+ </sect2>
+
+ <sect2 id="matchingOnAnnotationValues" xreflabel="matchingOnAnnotationValues">
+ <title>Matching based on annotation values</title>
+ <para>
+ The <literal>if</literal> pointcut designator can be used to write pointcuts
+ that match based on the values annotation members. For example:
+ </para>
+
+ <programlisting><![CDATA[
+pointcut txRequiredMethod(Tx transactionAnnotation) :
+ execution(* *(..)) && @this(transactionAnnotation)
+ && if(transactionAnnotation.policy() == TxPolicy.REQUIRED);
+]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <!-- ============================== -->
+
+ <sect1 id="annotations-decp">
+ <title>Using Annotations with declare statements</title>
+
+ <sect2 id="declare-error-and-declare-warning" xreflabel="declare-error-and-declare-warning">
+ <title>Declare error and declare warning</title>
+
+ <para>
+ Since pointcut expressions in AspectJ 5 support join point matching based
+ on annotations, this facility can be exploited when writing
+ <literal>declare warning</literal> and <literal>declare error</literal>
+ statements. For example:
+ </para>
+
+ <programlisting><![CDATA[
+declare warning : withincode(@PerformanceCritical * *(..)) &&
+ call(@ExpensiveOperation * *(..))
+ : "Expensive operation called from within performance critical section";
+]]></programlisting>
+
+ <programlisting><![CDATA[
+declare error : call(* org.xyz.model.*.*(..)) &&
+ !@within(Trusted)
+ : "Untrusted code should not call the model classes directly";
+]]></programlisting>
+
+ </sect2>
+
+
+ <sect2 id="declare-parents" xreflabel="declare-parents">
+ <title>declare parents</title>
+
+ <para>
+ The general form of a <literal>declare parents</literal> statement is:
+ </para>
+
+ <programlisting><![CDATA[
+declare parents : TypePattern extends Type;
+declare parents : TypePattern implements TypeList;
+]]></programlisting>
+
+ <para>
+ Since AspectJ 5 supports annotations as part of a type pattern
+ specification, it is now possible to match types based on the presence
+ of annotations <emphasis>with either class-file or runtime retention</emphasis>.
+ For example:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>declare parents : (@Secured *) implements SecuredObject;</term>
+ <listitem>
+ <para>
+ All types with the <literal>@Secured</literal> annotation
+ implement the <literal>SecuredObject</literal> inteface.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>declare parents : (@Secured BankAccount+) implements SecuredObject;</term>
+ <listitem>
+ <para>
+ The subset of types drawn from the <literal>BankAccount</literal> type and any subtype of
+ <literal>BankAccount</literal>, where the
+ <literal>@Secured</literal> annotation is present, implement the
+ <literal>SecuredObject</literal> interface.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>An annotation type may not be used as the target of a declare parents
+ statement. If an annotation type is named explicitly as the target of a
+ declare parents statement, a compilation error will result. If an annotation
+ type is matched by a non-explicit type pattern used in a declare parents
+ statement it will be ignored (and an XLint warning issued).</para>
+
+ </sect2>
+
+ <sect2 id="declare-precedence" xreflabel="declare-precedence">
+ <title>declare precedence</title>
+
+ <para>
+ The general form of a declare precedence statement is:
+ </para>
+
+ <programlisting><![CDATA[
+declare precedence : TypePatList;
+]]></programlisting>
+
+ <para>
+ AspectJ 5 allows the type patterns in the list to include annotation information
+ as part of the pattern specification. For example:
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>declare precedence : (@Security *),*;</term>
+ <listitem>
+ <para>
+ All aspects with the <literal>@Security</literal> annotation
+ take precedence over any other aspects in the system. (Or, more
+ informally, all security-related aspects take precedence).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+ </sect1>
+
+ <!-- ============================== -->
+
+ <sect1 id="annotations-declare">
+ <title>Declare Annotation</title>
+
+ <para>AspectJ 5 supports a new kind of declare statement, <literal>declare annotation</literal>.
+ This takes different forms according to the recipient of the annotation:
+ <literal>declare @type</literal> for types, <literal>declare @method</literal> for methods,
+ <literal>declare @constructor</literal> for constructors, and <literal>declare @field</literal>
+ for fields. <literal>declare @package</literal> may be supported in a future release.
+ </para>
+
+ <para>The general form is:</para>
+
+ <programlisting><![CDATA[
+declare @<kind> : ElementPattern : Annotation ;
+]]></programlisting>
+
+ <para>Where annotation is a regular annotation expression as defined in the Java 5 language. If the annotation has
+ the <literal>@Target</literal> meta-annotation, then the elements matched by <literal>ElementPattern</literal>
+ must be of the kind specified by the <literal>@Target</literal> annotation.</para>
+
+ <para><literal>ElementPattern</literal> is defined as follows:</para>
+
+ <programlisting><![CDATA[
+ElementPattern := TypePattern |
+ MethodPattern |
+ ConstructorPattern |
+ FieldPattern
+]]></programlisting>
+
+ <para>The following examples illustrate the use of <literal>declare annotation</literal>.</para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>declare @type : org.xyz.model..* : @BusinessDomain ;</term>
+ <listitem>
+ <para>
+ All types defined in a package with the prefix <literal>org.xyz.model</literal>
+ have the <literal>@BusinessDomain</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>declare @method : public * BankAccount+.*(..) : @Secured(role="supervisor")</term>
+ <listitem>
+ <para>
+ All public methods in <literal>BankAccount</literal> and its subtypes have the
+ annotation <literal>@Secured(role="supervisor")</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>declare @constructor : BankAccount+.new(..) : @Secured(role="supervisor")</term>
+ <listitem>
+ <para>
+ All constructors in <literal>BankAccount</literal> and its subtypes have the
+ annotation <literal>@Secured(role="supervisor")</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>declare @field : * DAO+.* : @Persisted;</term>
+ <listitem>
+ <para>
+ All fields defined in <literal>DAO</literal> or its subtypes have the
+ <literal>@Persisted</literal> annotation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect1>
+
+ <sect1 id="annotations-itds">
+ <title>Inter-type Declarations</title>
+
+ <para>An annotation type may not be the target of an inter-type declaration.</para>
+ </sect1>
+
+</chapter>
+
+