<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.
+ on the annotated element. Annotation patterns are defined by the following
+ grammar.
</para>
<programlisting><![CDATA[
- AnnotationPattern := AnnotationName |
- '!' AnnotationPattern |
- '(' AnnotationPatern '&&' AnnotationPattern ')' |
- '(' AnnotationPattern '||' AnnotationPattern ')' |
- '(' AnnotationPattern ')'
+ AnnotationPattern := '@' AnnotationTypePattern AnnotationPattern* |
+ '!' AnnotationPattern
+
+ AnnotationTypePattern := FullyQualifiedName |
+ '(' TypePattern ')'
- AnnotationName := '@' JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*
+ FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)*
]]></programlisting>
- <para>For example:</para>
+ <para>In simple terms, an annotation pattern element has one of two basic
+ forms:</para>
+
+ <itemizedlist>
+ <listitem>@<qualified-name>, for example, @Foo, or
+ @org.xyz.Foo.</listitem>
+ <listitem>@(<type-pattern>), for example, @(org.xzy..*), 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>
<programlisting><![CDATA[
@Immutable
]]></programlisting>
- <para>Matches any annotated element which has an annotation of type <literal>@Immutable</literal>.</para>
+ <para>Matches any annotated element which has an annotation of
+ type <literal>Immutable</literal>.</para>
<programlisting><![CDATA[
!@Persistent
]]></programlisting>
- <para>Matches any annotated element which does not have an annotation of type <literal>@Persistent</literal>.</para>
+ <para>Matches any annotated element which does not have an annotation of
+ type <literal>Persistent</literal>.</para>
<programlisting><![CDATA[
- (@Foo && @Goo)
+ @Foo @Goo
]]></programlisting>
- <para>Matches any annotated element which has both an annotation of type <literal>@Foo</literal> and
- an annotation of type <literal>@Goo</literal>. (The parenthesis are required in this example).</para>
+ <para>Matches any annotated element which has both an annotation of type <literal>Foo</literal> and
+ an annotation of type <literal>Goo</literal>.</para>
<programlisting><![CDATA[
- (@Foo || @Goo)
+ @(Foo || Goo)
]]></programlisting>
- <para>Matches any annotated element which has 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>
+ <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>
+
+ <programlisting><![CDATA[
+ @(org.xyz..*)
+ ]]></programlisting>
+
+ <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>
</sect2>
<sect2>
<title>Type Patterns</title>
- <para>In AspectJ 1.2, type patterns have the following form:</para>
-
- <programlisting><![CDATA[
- TypePattern := IdPattern |
- '!' TypePattern |
- TypePattern '&&' TypePattern |
- TypePattern '||' TypePattern |
- TypePattern '+' |
- TypePattern ('[]')* |
- '(' TypePattern ')'
-
- IdPattern := SimpleNamePattern |
- SimpleNamePattern '.' SimpleNamePattern |
- SimpleNamePattern '..' SimpleNamePattern
-
- SimpleNamePattern := ('*' | JavaIdentifierCharacter)+
- ]]></programlisting>
-
<para>AspectJ 1.5 extends type patterns to allow an optional <literal>AnnotationPattern</literal>
- prefix.</para>
+ prefix. (Extensions to this definition for generics are shown in the next chapter).</para>
<programlisting><![CDATA[
- TypePattern := PlainTypePattern |
+ TypePattern := SimpleTypePattern |
'!' TypePattern |
- '(' AnnotationPattern PlainTypePattern ')'|
+ '(' AnnotationPattern? TypePattern ')'
TypePattern '&&' TypePattern |
TypePattern '||' TypePattern |
- '(' TypePattern ')'
- OptionalParensTypePattern := TypePattern |
- AnnotationPattern PlainTypePattern
-
- PlainTypePattern := IdPattern |
- '!' PlainTypePattern |
- PlainTypePattern '&&' TypePattern |
- PlainTypePattern '||' TypePattern |
- PlainTypePattern '+' |
- PlainTypePattern ('[]')* |
- '(' PlainTypePattern ')'
-
- IdPattern := SimpleNamePattern |
- SimpleNamePattern '.' SimpleNamePattern |
- SimpleNamePattern '..' SimpleNamePattern
-
- SimpleNamePattern := ('*' | JavaIdentifierCharacter)+
+ 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>this</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
(@Immutable *)
]]></programlisting>
- <para>Matches any type with the <literal>@Immutable</literal> annotation.</para>
+ <para>Matches any type with an <literal>@Immutable</literal> annotation.</para>
<programlisting><![CDATA[
(!@Immutable *)
]]></programlisting>
- <para>Matches any type which does not have the <literal>@Immutable</literal> annotation.</para>
+ <para>Matches any type which does not have an <literal>@Immutable</literal> annotation.</para>
<programlisting><![CDATA[
(@Immutable (org.xyz.* || org.abc.*))
packages with the <literal>@Immutable</literal> annotation.</para>
<programlisting><![CDATA[
- (@Immutable Foo+ || Goo)
+ ((@Immutable Foo+) || Goo)
]]></programlisting>
<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>. An <literal>AnnotationPattern</literal> has higher
- precedence than <literal>&&</literal> or <literal>||</literal>, so the previous expression
- is equivalent to <literal>((@Immutable Foo+) || Goo)</literal>.</para>
+ annotation, or a type <literal>Goo</literal>.</para>
<programlisting><![CDATA[
- ((@Immutable || @NonPersistent) org.xyz..*)
+ ((@(Immutable || NonPersistent) org.xyz..*)
]]></programlisting>
<para>
<literal>@NonPersistent</literal> annotation.
</para>
+ <programlisting><![CDATA[
+ (@Immutable @NonPersistent org.xyz..*)
+ ]]></programlisting>
+
+ <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>
+
+ <programlisting><![CDATA[
+ (@(@Inherited *) org.xyz..*)
+ ]]></programlisting>
+
+ <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>
+
</sect2>
<sect2 id="signaturePatterns" xreflabel="Signature Patterns">
<programlisting><![CDATA[
FieldPattern :=
AnnotationPattern? FieldModifiersPattern?
- TypePattern (TypePattern '.')? SimpleNamePattern
+ TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
- FieldModifiersPattern := FieldModifier*
-
+ FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
+
FieldModifier := 'public' | 'private' | 'protected' | 'static' |
'transient' | 'final'
-
+
+ DotOrDotDot := '.' | '..'
+
+ SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
]]></programlisting>
<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>
<para>A <literal>MethodPattern</literal> is of the form</para>
<programlisting><![CDATA[
MethodPattern :=
- AnnotationPattern? ModifiersPattern? TypePattern
- (TypePattern '.')? SimpleNamePattern '(' FormalsPattern ')'
- ThrowsPattern?
+ AnnotationPattern? MethodModifiersPattern? TypePattern
+ (TypePattern DotOrDotDot)? SimpleNamePattern
+ '(' FormalsPattern ')'ThrowsPattern?
- ModifiersPattern := Modifier*
+ MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern*
- Modifier := 'public' | 'private' | 'protected' | 'static' |
- 'synchronized' | 'final'
+ MethodModifier := 'public' | 'private' | 'protected' | 'static' |
+ 'synchronized' | 'final'
FormalsPattern := '..' (',' FormalsPatternAfterDotDot)* |
- OptionalParensTypePattern (',' FormalsPattern)*
-
- FormalsPatternAfterDotDot := OptionalParensTypePattern (',' FormalsPatternAfterDotDot)*
+ OptionalParensTypePattern (',' FormalsPattern)* |
+ TypePattern '...'
+ FormalsPatternAfterDotDot :=
+ OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* |
+ TypePattern '...'
+
ThrowsPattern := 'throws' TypePatternList
TypePatternList := TypePattern (',' TypePattern)*
<programlisting><![CDATA[
ConstructorPattern :=
- AnnotationPattern? ModifiersPattern?
- (TypePattern '.')? 'new' '(' FormalsPattern ')'
+ 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 patterns restricts matches to methods/constructors with
+ method or constructor pattern restricts matches to methods/constructors with
annotations that match the pattern. For example:
</para>
</para>
</listitem>
</varlistentry>
-
</variablelist>
</sect2>
<term>within(@Secure *)</term>
<listitem>
<para>
- Matches any join point occuring in a type with an <literal>@Secure</literal>
+ 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>
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, @call, @execution, @adviceexecution, @get, @set,
- @staticinitialization, @initialization,</literal>, and <literal>@preinitialization</literal>
+ @within, @withincode</literal>, and <literal>@annotation</literal>
</para>
<para>It is a compilation error to attempt to match on an annotation type
</para>
<programlisting><![CDATA[
- ThisAnnotation := '@this' '(' AnnotationNameOrVar ')'
-
- TargetAnnotation := '@target' '(' AnnotationNameOrVar ')'
-
- ArgsAnnotation := '@args' '(' ArgsAnnotationPattern ')'
-
- ArgsAnnotationPattern := AnnotationNameOrVar (',' ArgsAnnotationPattern)? |
- '*' (',' ArgsAnnotationPattern)? |
- '..' (',' SingleArgsAnnotationPattern)*
-
- SingleArgsAnnotationPattern := AnnotationNameOrVar (',' SingleArgsAnnotationPattern)? |
- '*' (',' SingleArgsAnnotationPattern)?
-
- AnnotationNameOrVar := AnnotationName |
- JavaIdentifierCharacter+
+ AtThis := '@this' '(' AnnotationOrIdentifer ')'
+
+ AtTarget := '@target' '(' AnnotationOrIdentifier ')'
+
+ AnnotationOrIdentifier := '@' FullyQualifiedName | Identifier
+
+ AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
+
+ AnnotationsOrIdentifiersPattern :=
+ '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
+ '*' (',' AnnotationsOrIdentifiersPattern)*
+
+ AnnotationsOrIdentifiersPatternAfterDotDot :=
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
+ '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
+
]]></programlisting>
<para>
<para>
The <literal>@within</literal> and <literal>@withincode</literal> pointcut designators
- match any join point where the enclosing type (<literal>@within</literal>), or
- method/constructor (<literal>@withincode</literal>) has an annotation of the specified
+ 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[
- WithinAnnotation := '@within' '(' AnnotationNameOrVar ')'
-
- WithinCodeAnnotation := '@withincode' '(' AnnotationNameOrVar ')'
+ AtWithin := '@within' '(' AnnotationOrIdentifier ')'
+ AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
]]></programlisting>
<para>Some examples of using these designators follow:</para>
<term>@within(@Foo)</term>
<listitem>
<para>
- Matches any join point where the enclosing type
- has an annotation of type <literal>Foo</literal>.
+ 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>
@withincode(c);</term>
<listitem>
<para>
- Matches any join point whose shadow is lexically enclosed
- in a method which has an annotation of type <literal>@Critical</literal>,
+ 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>
</variablelist>
- <para>The remaining annotation-based pointcut designators are defined in a
- similar fashion:</para>
+ <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[
- CallAnnotation := '@call' '(' AnnotationNameOrVar ')'
-
- ExecutionAnnotation := '@execution' '(' AnnotationNameOrVar ')'
-
- AdviceExecution := '@adviceexecution' '(' AnnotationNameOrVar ')'
-
- GetAnnotation := '@set' '(' AnnotationNameOrVar ')'
-
- SetAnnotation := '@get' '(' AnnotationNameOrVar ')'
-
- InitializationAnnotation := '@initialization' '(' AnnotationNameOrVar ')'
-
- PreInitializationAnnotation := '@preinitialization' '(' AnnotationNameOrVar ')'
-
- StaticInitializationAnnotation := '@staticinitialization' '(' AnnotationNameOrVar ')'
-
- ]]></programlisting>
-
- <variablelist>
-
- <varlistentry>
- <term>@call(@Foo)</term>
- <listitem>
- <para>
- Matches any call join point where the most specific join point
- signature has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@execution(@Foo)</term>
- <listitem>
- <para>
- Matches any execution join point where the most specific join point
- signature has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@adviceexecution(@Foo)</term>
- <listitem>
- <para>
- Matches any advice execution join point where the advice
- has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@get(@Foo)</term>
- <listitem>
- <para>
- Matches any get join point where the target field
- has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@set(@Foo)</term>
- <listitem>
- <para>
- Matches any set join point where the target field
- has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@initialization(@Foo)</term>
- <listitem>
- <para>
- Matches any initialization join point where the initiating
- constructor has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@preinitialization(@Foo)</term>
- <listitem>
- <para>
- Matches any preinitialization join point where the initiating
- constructor has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>@staticinitialization(@Foo)</term>
- <listitem>
- <para>
- Matches any staticinitialization join point where the type being
- initialized has an annotation of type <literal>@Foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- </variablelist>
+ 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
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>
expressions before commiting to any one approach.</emphasis>
</para>
+<!-- @withinpackage ??? -->
+
<!--
<para>
Java 5 allows both packages and parameters to be annotated. To allow matching on package and parameter annotations,
<sect2>
<title>Limitations</title>
- <para>AspectJ 5 allows you to annotate advice, but there is no way to qualify advice execution
- join point matching based on the presence of annotations.</para>
-
<para>
It would be useful to be able to match join points based on
annotation values, rather than merely the presence of a
<programlisting><![CDATA[
declare error : call(* org.xyz.model.*.*(..)) &&
- @package(@Untrusted)
+ !@within(@Trusted *)
: "Untrusted code should not call the model classes directly";
]]></programlisting>
<title>A Grammar for the AspectJ 5 Language</title>
- Collect together all the grammar fragments scattered throughout this documented
- and present them as a coherent whole...
-
+ <programlisting><![CDATA[
+ === type patterns ===
+
+ 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+)*
+
+ === annotation patterns ===
+
+ AnnotationPattern := '@' AnnotationTypePattern AnnotationPattern* |
+ '!' AnnotationPattern
+
+ AnnotationTypePattern := FullyQualifiedName |
+ '(' TypePattern ')'
+
+ === signature patterns ===
+
+ -- field --
+
+ FieldPattern :=
+ AnnotationPattern? FieldModifiersPattern?
+ TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern
+
+ FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern*
+
+ FieldModifier := 'public' | 'private' | 'protected' | 'static' |
+ 'transient' | 'final'
+
+ DotOrDotDot := '.' | '..'
+
+ SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)?
+
+ -- method --
+
+ 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)*
+
+ -- constructor --
+
+ ConstructorPattern :=
+ AnnotationPattern? ConstructorModifiersPattern?
+ (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')'
+ ThrowsPattern?
+
+ ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern*
+
+ ConstructorModifier := 'public' | 'private' | 'protected'
+
+ === Pointcuts ===
+
+ PointcutPrimitive :=
+ Call | Execution | Get | Set | Handler |
+ Initialization | PreInitialization |
+ StaticInitialization | AdviceExecution |
+ This | Target | Args | CFlow | CFlowBelow |
+ Within | WithinCode | If |
+ AnnotationPointcut
+
+ AnnotationPointcut := AtAnnotation | AtThis | AtTarget |
+ AtWithin | AtWithinCode | AtArgs
+
+
+ Call := 'call' '(' MethodOrConstructorPattern ')'
+
+ MethodOrConstructorPattern := MethodPattern | ConstructorPattern
+
+ Execution := 'execution' '(' MethodOrConstructorPattern ')'
+
+ Get := 'get' '(' FieldPattern ')'
+ Set := 'set' '(' FieldPattern ')'
+ Handler := 'handler' '(' OptionalParensTypePattern ')'
+ Initialization := 'initialization' '(' ConstructorPattern ')'
+ PreInitialization := 'preinitialization' '(' ConstructorPattern ')'
+ StaticInitialization := 'staticinitialization' '(' OptionalParensTypePattern ')'
+ AdviceExecution := 'adviceexecution' '(' ')'
+ This := 'this' '(' TypeOrIdentifier ')'
+ Target := 'target' '(' TypeOrIdentifier ')'
+ Args := 'args' '(' FormalsOrIdentifiersPattern ')'
+ CFlow := 'cflow' '(' Pointcut ')'
+ CFlowBelow := 'cflowbelow' '(' Pointcut ')'
+ Within := 'within' '(' OptionalParensTypePattern ')'
+ WithinCode := 'withincode' '(' OptionalParensTypePattern ')'
+ If := 'if' '(' BooleanJavaExpression ')'
+
+ TypeOrIdentifier := FullyQualifiedName ('[' ']')* | Identifier
+ Identifier := JavaIdentifierChar+
+
+ FormalsOrIdentifiersPattern :=
+ '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? |
+ TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* |
+ '*' (',' FormalsOrIdentifiersPattern)*
+
+ FormalsOrIdentifiersPatternAfterDotDot :=
+ TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* |
+ '*' (',' FormalsOrIdentifiersPatternAfterDotDot)*
+
+ AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')'
+ AtThis := '@this' '(' AnnotationOrIdentifer ')'
+ AtTarget := '@target' '(' AnnotationOrIdentifier ')'
+ AtWithin := '@within' '(' AnnotationOrIdentifier ')'
+ AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')'
+
+ AnnotationOrIdentifier := '@' FullyQualifiedName | Identifier
+
+ AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')'
+
+ AnnotationsOrIdentifiersPattern :=
+ '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? |
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* |
+ '*' (',' AnnotationsOrIdentifiersPattern)*
+
+ AnnotationsOrIdentifiersPatternAfterDotDot :=
+ AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* |
+ '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)*
+
+ PointcutDeclaration := PointcutModifiers? 'pointcut' Identifier Formals
+ ':' PointcutExpression
+
+ PointcutModifiers := PointcutModifier*
+
+ PointcutModifier := 'public' | 'private' | 'protected' | 'abstract'
+
+ Formals := '(' ParamList? ')'
+ ParamList := FullyQualifiedName Identifier (',' ParamList)*
+
+ ReferencePointcut := (FullyQualifiedName '.')? Identifier Formals
+
+ PointcutExpression := (PointcutPrimitive | ReferencePointcut) |
+ '!' PointcutExpression |
+ '(' PointcutExpression ')' |
+ PointcutExpression '&&' PointcutExpression |
+ PointcutExpression '||' PointcutExpression
+
+ === Advice ===
+
+ to be written...
+
+ === Inter-type Declarations ===
+
+ to be written...
+
+ === Declare Statements ===
+
+ to be written...
+
+ === Aspects ===
+
+ to be written...
+
+ ]]></programlisting>
+
+
</appendix>
<listitem>The signature pattern (exactly) matches at least one
signature of the join point</listitem>
<listitem>The modifiers pattern matches the modifiers of the
- join point</listitem>
+ subject of the join point</listitem>
</orderedlist>
<para>These rules make it very easily to quickly determine whether a
given pointcut matches a given join point. In the next two sections,
we describe what the signature(s) of a join point are, and what the
- modifiers of a join point are.</para>
+ subjects of join points are.</para>
</sect1>
<sect1 id="join-point-signatures">
<title>Join Point Signatures</title>
- <para>Call and execution join points may potentially have multiple
+ <para>Call, execution, get, and set join points may potentially have multiple
signatures. All other join points have exactly one signature. The
following table summarizes the constituent parts of a join point
signature for the different kinds of join point.</para>
signature.</para>
<para>The signatures for most of the join point kinds should be
- self-explanatory, except for method call and execution
+ self-explanatory, except for field get and set, and method call and execution
join points, which can have multiple signatures. Each signature of
a method call or execution join point has the same id and parameter
types, but the declaring type and return type (with covariance) may vary.
+ Each signature of a field get or set join point has the same id and field
+ type, but the declaring type may vary.
</para>
- <para>The following sections examine signatures for method call and
- execution join points in more detail.</para>
+ <para>The following sections examine signatures for these join points
+ in more detail.</para>
<sect2>
<title>Method call join point signatures</title>
the method.</para>
</sect2>
-
+
+ <sect2>
+ <title>Field get and set join point signatures</title>
+
+ <para>
+ For a field get join point where an access is made to a field
+ <literal>f</literal> of type <literal>F</literal>
+ on a object with declared type <literal>T</literal>, then
+ <literal>F T.f</literal> is a signature of the get join point.
+ </para>
+
+ <para>
+ If <literal>T</literal> does not directly declare a member
+ <literal>f</literal>, then for each super type <literal>S</literal>
+ of <literal>T</literal>, up to and including the most specific
+ super type of <literal>T</literal> that does declare the member
+ <literal>f</literal>, <literal>F S.f</literal> is a signature
+ of the join point. For example, given the hierarchy:
+ </para>
+
+ <programlisting><![CDATA[
+ class P {
+ F f;
+ }
+
+ class S extends P {
+ F f;
+ }
+
+ class T extends S { }
+ ]]></programlisting>
+
+ <para>
+ Then the join point signatures for a field get join point of
+ the field <literal>f</literal> on an object with declared type
+ <literal>T</literal> are:
+ </para>
+
+ <programlisting><![CDATA[
+ F S.f
+ F T.f
+ ]]></programlisting>
+
+ <para>The signatures for a field set join point are derived in an
+ identical manner.</para>
+
+ </sect2>
+
</sect1>
<sect1 id="join-point-modifiers">
<para>Every join point has a single set of modifiers - these include
the standard Java modifiers such as <literal>public, private,
static, abstract</literal> etc., any annotations, and the throws
- clauses of methods and constructors.</para>
+ clauses of methods and constructors. These modifiers are the
+ modifiers of the <emphasis>subject</emphasis> of the join point.</para>
<para>
- For the different join point kinds, the modifiers are:
+ The following table defines the join point subject for each kind
+ of join point.
</para>
- <informaltable>
+ <informaltable>
<tgroup cols="2">
<thead>
<row>
<entry>Join Point Kind</entry>
- <entry>Join Point Modifiers</entry>
+ <entry>Subject</entry>
</row>
</thead>
<tbody>
<row>
<entry>Method call</entry>
- <entry>The modifiers of the method picked out by Java as
+ <entry>The method picked out by Java as
the static target of the method call.</entry>
</row>
<row>
<entry>Method execution</entry>
- <entry>The modifiers of the method that is executing.</entry>
+ <entry>The method that is executing.</entry>
</row>
<row>
<entry>Constructor call</entry>
- <entry>The modifiers of the constructor being called.</entry>
+ <entry>The constructor being called.</entry>
</row>
<row>
<entry>Constructor execution</entry>
- <entry>The modifiers of the constructor executing.</entry>
+ <entry>The constructor executing.</entry>
</row>
<row>
<entry>Field get</entry>
- <entry>The modifiers of the field being accessed.</entry>
+ <entry>The field being accessed.</entry>
</row>
<row>
<entry>Field set</entry>
- <entry>The modifiers of the field being set.</entry>
+ <entry>The field being set.</entry>
</row>
<row>
<entry>Pre-initialization</entry>
- <entry>The modifiers of the first constructor executing in
+ <entry>The first constructor executing in
this constructor chain.</entry>
</row>
<row>
<entry>Initialization</entry>
- <entry>The modifiers of the first constructor executing in
+ <entry>The first constructor executing in
this constructor chain.</entry>
</row>
<row>
<entry>Static initialization</entry>
- <entry>The modifiers of the type being initialized.</entry>
+ <entry>The type being initialized.</entry>
</row>
<row>
<entry>Handler</entry>
- <entry>No modifiers.</entry>
+ <entry>The declared type of the
+ exception being handled.</entry>
</row>
<row>
<entry>Advice execution</entry>
- <entry>The modifiers of the advice being executed.</entry>
+ <entry>The advice being executed.</entry>
</row>
</tbody>
</tgroup>
</informaltable>
-
- <para>For example, given the following types</para>
+
+ <para>For example, given the following types</para>
<programlisting><![CDATA[
public class X {
<listitem>The signature pattern (exactly) matches at least one
signature of the join point</listitem>
<listitem>The modifiers pattern matches the modifiers of the
- join point</listitem>
+ subject of the join point</listitem>
</orderedlist>
<para>Given the hierarchy</para>