<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>

