aboutsummaryrefslogtreecommitdiffstats
path: root/docs/adk15notebook/joinpointsignatures.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/adk15notebook/joinpointsignatures.xml')
-rw-r--r--docs/adk15notebook/joinpointsignatures.xml536
1 files changed, 536 insertions, 0 deletions
diff --git a/docs/adk15notebook/joinpointsignatures.xml b/docs/adk15notebook/joinpointsignatures.xml
new file mode 100644
index 000000000..e803b9cfd
--- /dev/null
+++ b/docs/adk15notebook/joinpointsignatures.xml
@@ -0,0 +1,536 @@
+<chapter id="jpsigs" xreflabel="Join Point Signatures">
+
+ <title>Join Point Signatures</title>
+
+ <para>
+ Many of the extensions to the AspectJ language to address the new features of
+ Java 5 are derived from a simple set of principles for join point
+ matching. In this section, we outline these principles as a foundation
+ for understanding the matching rules in the presence of annotations,
+ generics, covariance, varargs, and autoboxing.
+ </para>
+
+ <sect1 id="join-point-matching">
+ <title>Join Point Matching</title>
+
+ <para>AspectJ supports 11 different kinds of join points. These are
+ the <literal>method call, method execution, constructor call,
+ constructor execution, field get, field set, pre-initialization,
+ initialization, static initialization, handler,</literal> and
+ <literal>advice execution</literal> join points.</para>
+
+ <para>The <emphasis>kinded</emphasis> pointcut designators match
+ based on the kind of a join point. These are the <literal>call,
+ execution, get, set, preinitialization, initialization,
+ staticinitialization, handler,</literal> and <literal>adviceexecution</literal>
+ designators.</para>
+
+ <para>A kinded pointcut is written using patterns, some of which
+ match based on <emphasis>signature</emphasis>, and some of which
+ match based on <emphasis>modifiers</emphasis>. For example, in
+ the <literal>call</literal> pointcut designator:</para>
+
+ <programlisting><![CDATA[
+call(ModifierPattern TypePattern TypePattern.IdPattern(TypePatternList) ThrowsPattern)
+]]></programlisting>
+
+ <para>the modifiers matching patterns are <literal>ModifierPattern</literal>
+ and <literal>ThrowsPattern</literal>, and the signature matching patterns
+ are <literal>TypePattern TypePattern.IdPattern(TypePatternList)</literal>.
+ </para>
+
+ <para>
+ A join point has potentially multiple signatures, but only one set of
+ modifiers. <emphasis>A kinded primitive pointcut matches a particular join point
+ if and only if</emphasis>:
+ </para>
+
+ <orderedlist>
+ <listitem>They are of the same kind</listitem>
+ <listitem>The signature pattern (exactly) matches at least one
+ signature of the join point</listitem>
+ <listitem>The modifiers pattern matches the modifiers of the
+ 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
+ subjects of join points are.</para>
+
+ </sect1>
+
+ <sect1 id="join-point-signatures">
+ <title>Join Point Signatures</title>
+
+ <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>
+
+ <informaltable>
+ <tgroup cols="7">
+ <thead>
+ <row>
+ <entry>Join Point Kind</entry>
+ <entry>Return Type</entry>
+ <entry>Declaring Type</entry>
+ <entry>Id</entry>
+ <entry>Parameter Types</entry>
+ <entry>Field Type</entry>
+ <entry>Exception Type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Method call</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Method execution</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Constructor call</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Constructor execution</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Field get</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Field set</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Pre-initialization</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Initialization</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Static initialization</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ <row>
+ <entry>Handler</entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry></entry>
+ <entry>+</entry>
+ </row>
+ <row>
+ <entry>Advice execution</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry>+</entry>
+ <entry></entry>
+ <entry></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>Note that whilst an advice execution join point has a
+ signature comprising the declaring type of the advice and the
+ advice parameter types, the <literal>adviceexecution</literal>
+ pointcut designator does not support matching based on this
+ signature.</para>
+
+ <para>The signatures for most of the join point kinds should be
+ 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 these join points
+ in more detail.</para>
+
+ <sect2 id="method-call-join-point-signatures" xreflabel="method-call-join-point-signatures">
+ <title>Method call join point signatures</title>
+
+ <para>
+ For a call join point where a call is made to a method
+ <literal>m(parameter_types)</literal> on a target type <literal>T</literal> (where
+ <literal>T</literal> is the static type of the target):
+ </para>
+
+ <programlisting><![CDATA[
+T t = new T();
+t.m("hello"); <= call join point occurs when this line is executed
+]]></programlisting>
+
+ <para>
+ Then the signature <literal>R(T) T.m(parameter_types)</literal> is a signature
+ of the call join point, where <literal>R(T)</literal> is the return
+ type of <literal>m</literal> in <literal>T</literal>, and
+ <literal>parameter_types</literal> are the parameter types of
+ <literal>m</literal>. If <literal>T</literal> itself does not
+ declare a definition of <literal>m(parameter_types)</literal>, then
+ <literal>R(T)</literal> is the return type in the definition of
+ <literal>m</literal> that <literal>T</literal> inherits. Given the
+ call above, and the definition of <literal>T.m</literal>:
+ </para>
+
+ <programlisting><![CDATA[
+interface Q {
+ R m(String s);
+}
+
+class P implements Q {
+ R m(String s) {...}
+}
+
+class S extends P {
+ R' m(String s) {...}
+}
+
+class T extends S {}
+]]></programlisting>
+
+ <para>Then <literal>R' T.m(String)</literal> is a signature of the
+ call join point for <literal>t.m("hello")</literal>.</para>
+
+ <para>
+ For each ancestor (super-type) <literal>A</literal> of <literal>T</literal>,
+ if <literal>m(parameter_types)</literal> is defined for that super-type, then
+ <literal>R(A) A.m(parameter_types)</literal> is a signature of the call join
+ point, where <literal>R(A)</literal> is the return type of <literal>
+ m(parameter_types)</literal> as defined in <literal>A</literal>, or as inherited
+ by <literal>A</literal> if <literal>A</literal> itself does not
+ provide a definition of <literal>m(parameter_types)</literal>.
+ </para>
+
+ <para>
+ Continuing the example from above,we can deduce that
+ </para>
+
+ <programlisting><![CDATA[
+R' S.m(String)
+R P.m(String)
+R Q.m(String)
+]]></programlisting>
+
+ <para>are all additional signatures for the call join point arising
+ from the call <literal>t.m("hello")</literal>. Thus this call
+ join point has four signatures in total. Every signature has the same
+ id and parameter types, and a different declaring type.</para>
+
+ </sect2>
+
+ <sect2 id="method-execution-join-point-signatures" xreflabel="method-execution-join-point-signatures">
+ <title>Method execution join point signatures</title>
+
+ <para>Join point signatures for execution join points are defined
+ in a similar manner to signatures for call join points. Given the
+ hierarchy:
+ </para>
+
+
+ <programlisting><![CDATA[
+interface Q {
+ R m(String s);
+}
+
+class P implements Q {
+ R m(String s) {...}
+}
+
+class S extends P {
+ R' m(String s) {...}
+}
+
+class T extends S { }
+
+class U extends T {
+ R' m(String s) {...}
+}
+]]></programlisting>
+
+ <para>Then the execution join point signatures arising as a result
+ of the call to <literal>u.m("hello")</literal> are: </para>
+
+ <programlisting><![CDATA[
+R' U.m(String)
+R' S.m(String)
+R P.m(String)
+R Q.m(String)
+]]></programlisting>
+
+ <para>Each signature has the same id and parameter types, and a
+ different declaring type. There is one signature for each type
+ that provides its own declaration of the method. Hence in this
+ example there is no signature <literal>R' T.m(String)</literal>
+ as <literal>T</literal> does not provide its own declaration of
+ the method.</para>
+
+ </sect2>
+
+ <sect2 id="field-get-and-set-join-point-signatures" xreflabel="field-get-and-set-join-point-signatures">
+ <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">
+ <title>Join Point Modifiers</title>
+
+ <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. These modifiers are the
+ modifiers of the <emphasis>subject</emphasis> of the join point.</para>
+
+ <para>
+ The following table defines the join point subject for each kind
+ of join point.
+ </para>
+
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Join Point Kind</entry>
+ <entry>Subject</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Method call</entry>
+ <entry>The method picked out by Java as
+ the static target of the method call.</entry>
+ </row>
+ <row>
+ <entry>Method execution</entry>
+ <entry>The method that is executing.</entry>
+ </row>
+ <row>
+ <entry>Constructor call</entry>
+ <entry>The constructor being called.</entry>
+ </row>
+ <row>
+ <entry>Constructor execution</entry>
+ <entry>The constructor executing.</entry>
+ </row>
+ <row>
+ <entry>Field get</entry>
+ <entry>The field being accessed.</entry>
+ </row>
+ <row>
+ <entry>Field set</entry>
+ <entry>The field being set.</entry>
+ </row>
+ <row>
+ <entry>Pre-initialization</entry>
+ <entry>The first constructor executing in
+ this constructor chain.</entry>
+ </row>
+ <row>
+ <entry>Initialization</entry>
+ <entry>The first constructor executing in
+ this constructor chain.</entry>
+ </row>
+ <row>
+ <entry>Static initialization</entry>
+ <entry>The type being initialized.</entry>
+ </row>
+ <row>
+ <entry>Handler</entry>
+ <entry>The declared type of the
+ exception being handled.</entry>
+ </row>
+ <row>
+ <entry>Advice execution</entry>
+ <entry>The advice being executed.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+
+ <para>For example, given the following types</para>
+
+ <programlisting><![CDATA[
+public class X {
+ @Foo
+ protected void doIt() {...}
+}
+
+public class Y extends X {
+ public void doIt() {...}
+}
+]]></programlisting>
+
+ <para>Then the modifiers for a call to <literal>(Y y) y.doIt()</literal>
+ are simply <literal>{public}</literal>. The modifiers for a call to
+ <literal>(X x) x.doIt()</literal> are <literal>{@Foo,protected}</literal>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="join-point-matching-summary">
+ <title>Summary of Join Point Matching</title>
+
+ <para>
+ A join point has potentially multiple signatures, but only one set of
+ modifiers. <emphasis>A kinded primitive pointcut matches a particular join point
+ if and only if</emphasis>:
+ </para>
+
+ <orderedlist>
+ <listitem>They are of the same kind</listitem>
+ <listitem>The signature pattern (exactly) matches at least one
+ signature of the join point</listitem>
+ <listitem>The modifiers pattern matches the modifiers of the
+ subject of the join point</listitem>
+ </orderedlist>
+
+ <para>Given the hierarchy</para>
+
+ <programlisting><![CDATA[
+interface Q {
+ R m(String s);
+}
+
+class P implements Q {
+ @Foo
+ public R m(String s) {...}
+}
+
+class S extends P {
+ @Bar
+ public R' m(String s) {...}
+}
+
+class T extends S {}
+]]></programlisting>
+
+ <para>and the program fragment:</para>
+
+ <programlisting><![CDATA[
+P p = new P();
+S s = new S();
+T t = new T();
+...
+p.m("hello");
+s.m("hello");
+t.m("hello");
+]]></programlisting>
+
+ <para>
+ The the pointcut <literal>call(@Foo R P.m(String))</literal> matches the
+ call <literal>p.m("hello")</literal> since both the signature and the
+ modifiers match. It does not match the call <literal>s.m("hello")</literal>
+ because even though the signature pattern matches one of the signatures
+ of the join point, the modifiers pattern does not match the modifiers of
+ the method m in S which is the static target of the call.
+ </para>
+
+ <para>The pointcut <literal>call(R' m(String))</literal> matches the
+ calls <literal>t.m("hello")</literal> and <literal>s.m("hello")</literal>.
+ It does not match the call <literal>p.m("hello")</literal> since the
+ signature pattern does not match any signature for the call join point
+ of m in P.</para>
+ </sect1>
+
+</chapter>
+