aboutsummaryrefslogtreecommitdiffstats
path: root/docs/progGuideDB
diff options
context:
space:
mode:
authorwisberg <wisberg>2002-12-16 17:58:19 +0000
committerwisberg <wisberg>2002-12-16 17:58:19 +0000
commitd842c4f1139629c1f062b74ba818d233b2c31043 (patch)
tree842d3871620bc0eb60edcd95e55804d67e0f61fa /docs/progGuideDB
parent3ce247199704eae6b2c92c6e38c69584e3250c52 (diff)
downloadaspectj-d842c4f1139629c1f062b74ba818d233b2c31043.tar.gz
aspectj-d842c4f1139629c1f062b74ba818d233b2c31043.zip
initial version
Diffstat (limited to 'docs/progGuideDB')
-rw-r--r--docs/progGuideDB/aspectjdoc.dsl124
-rw-r--r--docs/progGuideDB/aspects.gifbin0 -> 7071 bytes
-rw-r--r--docs/progGuideDB/bibliography.xml70
-rw-r--r--docs/progGuideDB/build.sh79
-rw-r--r--docs/progGuideDB/examples.xml2343
-rw-r--r--docs/progGuideDB/figureUML.gifbin0 -> 3480 bytes
-rw-r--r--docs/progGuideDB/gettingstarted.xml1090
-rw-r--r--docs/progGuideDB/glossary.xml192
-rw-r--r--docs/progGuideDB/idioms.xml104
-rw-r--r--docs/progGuideDB/language.xml1226
-rw-r--r--docs/progGuideDB/limitations.xml123
-rw-r--r--docs/progGuideDB/overview.gifbin0 -> 2576 bytes
-rw-r--r--docs/progGuideDB/pitfalls.xml103
-rw-r--r--docs/progGuideDB/preface.xml52
-rw-r--r--docs/progGuideDB/progguide.html.xsl9
-rw-r--r--docs/progGuideDB/progguide.xml83
-rw-r--r--docs/progGuideDB/quickreference.xml658
-rw-r--r--docs/progGuideDB/semantics.xml2361
-rw-r--r--docs/progGuideDB/telecom.gifbin0 -> 4047 bytes
19 files changed, 8617 insertions, 0 deletions
diff --git a/docs/progGuideDB/aspectjdoc.dsl b/docs/progGuideDB/aspectjdoc.dsl
new file mode 100644
index 000000000..37ce64bd6
--- /dev/null
+++ b/docs/progGuideDB/aspectjdoc.dsl
@@ -0,0 +1,124 @@
+<!DOCTYPE style-sheet PUBLIC "-//James Clark//DTD DSSSL Style Sheet//EN" [
+ <!ENTITY html-ss PUBLIC "-//Norman Walsh//DOCUMENT DocBook HTML Stylesheet//EN" CDATA DSSSL>
+ <!ENTITY print-ss PUBLIC "-//Norman Walsh//DOCUMENT DocBook Print Stylesheet//EN" CDATA DSSSL>
+]>
+
+<style-sheet>
+
+<!-- Customizations for the HTML version -->
+
+<style-specification id="html" use="html-stylesheet">
+<style-specification-body>
+
+;; Specify the CSS stylesheet to use
+(define %stylesheet% "../../style.css")
+
+;; Suppress Lists of Tables, Examples, ...
+(define ($generate-book-lot-list$)
+ '())
+
+;; Display only the first two section levels in the table of contents
+(define (toc-depth nd)
+ (if (string=? (gi nd) (normalize "book"))
+ 2
+ 1))
+
+;; Make references be appendices (or chapters), not parts.
+(define (en-label-number-format-list)
+ (list
+ (list (normalize "set") "1")
+ (list (normalize "book") "1")
+ (list (normalize "prefix") "1")
+ (list (normalize "part") "I")
+ (list (normalize "chapter") "1")
+ (list (normalize "appendix") "A")
+ ;;(list (normalize "reference") "1") ; references-as-chapters
+ (list (normalize "reference") "A") ; references-as-appendices
+ (list (normalize "example") "1")
+ (list (normalize "figure") "1")
+ (list (normalize "table") "1")
+ (list (normalize "procedure") "1")
+ (list (normalize "step") "1")
+ (list (normalize "refsect1") "1")
+ (list (normalize "refsect2") "1")
+ (list (normalize "refsect3") "1")
+ (list (normalize "sect1") "1")
+ (list (normalize "sect2") "1")
+ (list (normalize "sect3") "1")
+ (list (normalize "sect4") "1")
+ (list (normalize "sect5") "1")
+ (list (normalize "section") "1")
+ ))
+ ;;; for references-as-appendices
+ (define (reference-number-sibling-list cmp) (list (normalize "appendix")))
+ (define (appendix-number-sibling-list cmp) (list (normalize "reference")))
+ ;;; for references-as-chapters
+ ;;(define (reference-number-sibling-list cmp) (list (normalize "chapter")))
+ ;;(define (chapter-number-sibling-list cmp) (list (normalize "reference")))
+
+
+</style-specification-body>
+</style-specification>
+<external-specification id="html-stylesheet" document="html-ss">
+
+
+<!-- Customizations for the print version -->
+
+<style-specification id="print" use="print-stylesheet">
+<style-specification-body>
+
+;; Suppress Lists of Tables, Examples, ...
+(define ($generate-book-lot-list$)
+ '())
+
+;; Display only the first two section levels in the table of contents
+(define (toc-depth nd)
+ (if (string=? (gi nd) (normalize "book"))
+ 2
+ 1))
+
+(define %two-side% #t)
+(define bop-footnotes #t) ; doesn't seem to work
+
+;; Make references be appendices (or chapters), not parts.
+(define (en-label-number-format-list)
+ (list
+ (list (normalize "set") "1")
+ (list (normalize "book") "1")
+ (list (normalize "prefix") "1")
+ (list (normalize "part") "I")
+ (list (normalize "chapter") "1")
+ (list (normalize "appendix") "A")
+ ;;(list (normalize "reference") "1") ; references-as-chapters
+ (list (normalize "reference") "A") ; references-as-appendices
+ (list (normalize "example") "1")
+ (list (normalize "figure") "1")
+ (list (normalize "table") "1")
+ (list (normalize "procedure") "1")
+ (list (normalize "step") "1")
+ (list (normalize "refsect1") "1")
+ (list (normalize "refsect2") "1")
+ (list (normalize "refsect3") "1")
+ (list (normalize "sect1") "1")
+ (list (normalize "sect2") "1")
+ (list (normalize "sect3") "1")
+ (list (normalize "sect4") "1")
+ (list (normalize "sect5") "1")
+ (list (normalize "section") "1")
+ ))
+ ;;; for references-as-appendices
+ (define (reference-number-sibling-list cmp) (list (normalize "appendix")))
+ (define (appendix-number-sibling-list cmp) (list (normalize "reference")))
+ ;;; for references-as-chapters
+ ;;(define (reference-number-sibling-list cmp) (list (normalize "chapter")))
+ ;;(define (chapter-number-sibling-list cmp) (list (normalize "reference")))
+
+</style-specification-body>
+</style-specification>
+<external-specification id="print-stylesheet" document="print-ss">
+
+</style-sheet>
+
+<!-- Local Variables -->
+<!-- mode: scheme -->
+<!-- End -->
diff --git a/docs/progGuideDB/aspects.gif b/docs/progGuideDB/aspects.gif
new file mode 100644
index 000000000..8bca684ad
--- /dev/null
+++ b/docs/progGuideDB/aspects.gif
Binary files differ
diff --git a/docs/progGuideDB/bibliography.xml b/docs/progGuideDB/bibliography.xml
new file mode 100644
index 000000000..4d6c1f80f
--- /dev/null
+++ b/docs/progGuideDB/bibliography.xml
@@ -0,0 +1,70 @@
+<bibliography>
+
+ <title>Bibliography</title>
+
+<!-- <biblioentry> -->
+<!-- <authorgroup> -->
+<!-- <author> -->
+<!-- <firstname></firstname> <surname></surname> -->
+<!-- </author> -->
+<!-- </authorgroup> -->
+<!-- <title></title> -->
+<!-- <publisher> -->
+<!-- <publishername></publishername> -->
+<!-- <address><city></city></address> -->
+<!-- </publisher> -->
+<!-- <copyright><year></year></copyright> -->
+<!-- </biblioentry> -->
+
+<!-- The state element doesn't appear in HTML, so overload the city element. -->
+
+ <biblioentry>
+ <authorgroup>
+ <author>
+ <firstname>Doug</firstname> <surname>Lea</surname>
+ </author>
+ </authorgroup>
+ <title>Concurrent Programming in Java, Second Edition</title>
+ <publisher>
+ <publishername>Addison-Wesley</publishername>
+ <address><city>Reading, MA</city></address>
+ </publisher>
+ <copyright><year>1999</year></copyright>
+ </biblioentry>
+
+ <biblioentry>
+ <authorgroup>
+ <author>
+ <firstname>Gregor</firstname> <surname>Kiczales, et al</surname>
+ </author>
+ </authorgroup>
+ <title>An Overview of AspectJ</title>
+ <publisher>
+ <publishername>in Proceedings of the 5th European Conference on Object
+ Oriented Programming (ECOOP), Springer</publishername>
+ <address><city>Budapest, Hungary</city></address>
+ </publisher>
+ <copyright><year>2001</year></copyright>
+ </biblioentry>
+
+ <biblioentry>
+ <authorgroup>
+ <author>
+ <firstname>Betrand</firstname><surname>Meyer</surname>
+ </author>
+ </authorgroup>
+ <title>Object-Oriented Software Construction, 2/e</title>
+ <publisher>
+ <publishername>Prentice-Hall</publishername>
+ <address><city>New York, NY</city></address>
+ </publisher>
+ <copyright><year>1999</year></copyright>
+ </biblioentry>
+
+</bibliography>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.sgml" "book" "bibliography") -->
+<!-- End: -->
diff --git a/docs/progGuideDB/build.sh b/docs/progGuideDB/build.sh
new file mode 100644
index 000000000..19499ff3b
--- /dev/null
+++ b/docs/progGuideDB/build.sh
@@ -0,0 +1,79 @@
+#/bin/sh
+
+JAVA_HOME="/opt/IBMJava2-13"
+DOCBOOK_HOME="/usr/local/docbook"
+
+SAXON="/home/vladimir/aspectj-external-lib/saxon"
+XERCES="/usr/local/xerces-1_4_3"
+
+saxon() { java -cp $SAXON/saxon.jar com.icl.saxon.StyleSheet $*; }
+xerces() { java -cp $XERCES/xercesSamples.jar sax.SAXCount -v $* ; }
+
+# echo ""; echo ""
+# echo "The following REMARKS still exist:"; echo ""
+# egrep -n -A3 "<remark>" *.xml
+# echo ""; echo ""
+
+# echo "Checking for required RPMS..."
+# for RPM in docbook-dtd docbook-xsl; do
+# rpm -q $RPM >/dev/null
+# if [ $? = 1 ]; then
+# echo "${RPM}: Required RPM not installed. Exiting..."
+# exit 1
+# fi
+# done
+
+# echo "Checking for required programs..."
+# for PROG in java tex; do
+# type $PROG >/dev/null 2>/dev/null
+# if [ $? = 1 ]; then
+# echo "$prog not found in PATH. Exiting..."
+# exit 1
+# fi
+# done
+
+# echo "Checking for required files..."
+# for FILE in $JAVA_HOME/jre/lib/ext/saxon.jar; do
+# if [ ! -s $FILE ]; then
+# echo "$FILE not found. Exiting..."
+# exit 1
+# fi
+# done
+
+OPT=$1
+shift 1
+
+if [ "$OPT" == "-v" ]; then
+ COMMAND="xerces -v progguide.xml"
+ echo " Validating the XML source: $COMMAND"
+ ${COMMAND}
+fi
+
+if [ "$OPT" == "-t" ]; then
+ COMMAND='openjade -t tex -d aspectjdoc.dsl#print /usr/share/sgml/xml.dcl progguide.xml'
+ echo " Creating TeX from XML: $COMMAND"
+ ${COMMAND}
+ COMMAND="pdfjadetex progguide.tex"
+ echo " Creating PDF from TeX: $COMMAND"
+ ${COMMAND}
+ ${COMMAND}
+ exit
+fi
+
+COMMAND="saxon -w0 progguide.xml progguide.html.xsl"
+echo " Transforming XML to HTML: $COMMAND"
+${COMMAND}
+
+# echo "Transforming XML to FO..."
+# saxon -w0 -o progguide.fo progguide.xml ${XSL_STYLESHEET_HOME}/fo/docbook.xsl >progguide.fo.log 2>&1
+
+# echo -n "Transforming FO to PostScript"
+# tex --interaction nonstopmode -fmt /usr/local/texmf/tex/xmltex/base/xmltex progguide.fo >|progguide.ps.1.log 2>&1
+# echo "Pass 2..."
+# tex --interaction nonstopmode -fmt /usr/local/texmf/tex/xmltex/base/xmltex progguide.fo >|progguide.ps.2.log 2>&1
+# dvips progguide -o
+
+# echo "Transforming FO to PDF..."
+# pdflatex --interaction nonstopmode -fmt /usr/local/texmf/tex/xmltex/base/pdfxmltex progguide.fo >|progguide.pdf.log
+
+
diff --git a/docs/progGuideDB/examples.xml b/docs/progGuideDB/examples.xml
new file mode 100644
index 000000000..2e6a1715d
--- /dev/null
+++ b/docs/progGuideDB/examples.xml
@@ -0,0 +1,2343 @@
+<chapter id="examples" xreflabel="Examples">
+ <title>Examples</title>
+
+ <sect1><!-- About this Chapter -->
+ <title>About this Chapter</title>
+
+ <para>This chapter consists entirely of examples of AspectJ use.
+
+<!-- ADD THIS IN AGAIN WHEN IT'S TRUE
+ The
+ examples have been chosen because they illustrate common AspectJ usage
+ patterns or techniques. Care has been taken to ensure that they also
+ exhibit good style, in addition to being merely syntactically and
+ semantically correct.
+-->
+</para>
+
+ <para>The examples can be grouped into four categories:</para>
+
+ <simplelist columns="2" type="horiz">
+ <member><emphasis role="bold">technique</emphasis></member>
+ <member>Examples which illustrate how to use one or more features of the
+ language. </member>
+
+ <member><emphasis role="bold">development</emphasis></member>
+ <member>Examples of using AspectJ during the development phase of a
+ project. </member>
+
+ <member><emphasis role="bold">production</emphasis></member>
+ <member>Examples of using AspectJ to provide functionality in an
+ application. </member>
+
+ <member><emphasis role="bold">reusable</emphasis></member>
+ <member>Examples of reuse of aspects and pointcuts.</member>
+ </simplelist>
+
+ </sect1>
+
+
+ <sect1>
+ <title>Obtaining, Compiling and Running the Examples</title>
+
+ <para>The examples source code is part of AspectJ's documentation
+ distribution which may be downloaded from <ulink
+ url="http://aspectj.org/dl">the AspectJ download page</ulink>.</para>
+
+ <para>Compiling most examples should be straightforward. Go the
+ <filename><replaceable>InstallDir</replaceable>/examples</filename>
+ directory, and look for a <filename>.lst</filename> file in one of the
+ example subdirectories. Use the <literal>-arglist</literal> option to
+ <literal>ajc</literal> to compile the example. For instance, to compile
+ the telecom example with billing, type </para>
+
+<programlisting>
+ajc -argfile telecom/billing.lst
+</programlisting>
+
+ <para>To run the examples, your classpath must include the AspectJ run-time
+ Java archive (<literal>aspectjrt.jar</literal>). You may either set
+ the <literal>CLASSPATH</literal> environment variable or use the
+ <literal>-classpath</literal> command line option to the Java
+ interpreter:</para>
+
+<programlisting>
+(In Unix use a : in the CLASSPATH)
+java -classpath ".:<replaceable>InstallDir</replaceable>/lib/aspectjrt.jar" telecom.billingSimulation
+</programlisting>
+
+<programlisting>
+(In Windows use a ; in the CLASSPATH)
+java -classpath ".;<replaceable>InstallDir</replaceable>/lib/aspectjrt.jar" telecom.billingSimulation
+</programlisting>
+
+ </sect1>
+
+
+<!-- ============================================================ -->
+<!-- ============================================================ -->
+
+
+ <sect1>
+ <title>Basic Techniques</title>
+
+ <para>This section presents two basic techniques of using AspectJ, one each
+ from the two fundamental ways of capturing crosscutting concerns: with
+ dynamic join points and advice, and with static introduction. Advice
+ changes an application's behavior. Introduction changes both an
+ application's behavior and its structure. </para>
+
+ <para>The first example, <xref endterm="sec:JoinPointsAndtjp:title"
+ linkend="sec:JoinPointsAndtjp"/>, is about gathering and using
+ information about the join point that has triggered some advice. The
+ second example, <xref endterm="sec:RolesAndViews:title"
+ linkend="sec:RolesAndViews"/>, concerns changing an existing class
+ hierarchy. </para>
+
+<!-- ======================================== -->
+
+ <sect2 id="sec:JoinPointsAndtjp"><!-- Join Points and thisJoinPoint -->
+ <title>Join Points and <literal>thisJoinPoint</literal></title>
+ <titleabbrev id="sec:JoinPointsAndtjp:title">Join Points and
+ <literal>thisJoinPoint</literal></titleabbrev>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/tjp</filename>.)</para>
+
+ <para>A join point is some point in the
+ execution of a program together with a view into the execution context
+ when that point occurs. Join points are picked out by pointcuts. When a
+ join point is reached, before, after or around advice on that join
+ point may be run. </para>
+
+ <para>When dealing with pointcuts that pick out join points of specific
+ method calls, field gets, or the like, the advice will know exactly what
+ kind of join point it is executing under. It might even have access to
+ context given by its pointcut. Here, for example, since the only join
+ points reached will be calls of a certain method, we can get the target
+ and one of the args of the method directly.
+ </para>
+
+<programlisting><![CDATA[
+before(Point p, int x): target(p)
+ && args(x)
+ && call(void setX(int)) {
+ if (!p.assertX(x)) {
+ System.out.println("Illegal value for x"); return;
+ }
+}
+]]></programlisting>
+
+ <para>But sometimes the join point is not so clear. For
+ instance, suppose a complex application is being debugged, and one
+ would like to know when any method in some class is being executed.
+ Then, the pointcut </para>
+
+<programlisting><![CDATA[
+pointcut execsInProblemClass(): within(ProblemClass)
+ && execution(* *(..));
+]]></programlisting>
+
+ <para>will select all join points where a method defined within the class
+ <classname>ProblemClass</classname> is being executed. But advice
+ executes when a particular join point is matched, and so the question,
+ "Which join point was matched?" naturally arises.</para>
+
+ <para>Information about the join point that was matched is available to
+ advice through the special variable <varname>thisJoinPoint</varname>,
+ of type <ulink
+ url="../api/org/aspectj/lang/JoinPoint.html"><classname>org.aspectj.lang.JoinPoint</classname></ulink>. This
+ class provides methods that return</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>the kind of join point that was matched
+ </listitem>
+ <listitem>the source location of the current join point
+ </listitem>
+ <listitem>normal, short and long string representations of the
+ current join point</listitem>
+ <listitem>the actual argument(s) to the method or field selected
+ by the current join point </listitem>
+ <listitem>the signature of the method or field selected by the
+ current join point</listitem>
+ <listitem>the target object</listitem>
+ <listitem>the currently executing object</listitem>
+ <listitem>a reference to the static portion of the object
+ representing the current join point. This is also available through
+ the special variable <varname>thisJoinPointStaticPart</varname>.</listitem>
+
+ </itemizedlist>
+
+ <sect3>
+ <title>The <classname>Demo</classname> class</title>
+
+ <para>The class <classname>tjp.Demo</classname> in
+ <filename>tjp/Demo.java</filename> defines two methods
+ <literal>foo</literal> and <literal>bar</literal> with different
+ parameter lists and return types. Both are called, with suitable
+ arguments, by <classname>Demo</classname>'s <function>go</function>
+ method which was invoked from within its <function>main</function>
+ method. </para>
+
+<programlisting><![CDATA[
+public class Demo {
+
+ static Demo d;
+
+ public static void main(String[] args){
+ new Demo().go();
+ }
+
+ void go(){
+ d = new Demo();
+ d.foo(1,d);
+ System.out.println(d.bar(new Integer(3)));
+ }
+
+ void foo(int i, Object o){
+ System.out.println("Demo.foo(" + i + ", " + o + ")\n");
+ }
+
+
+ String bar (Integer j){
+ System.out.println("Demo.bar(" + j + ")\n");
+ return "Demo.bar(" + j + ")";
+ }
+
+}
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Aspect <literal>GetInfo</literal></title>
+
+ <para>This aspect uses around advice to intercept the execution of
+ methods <literal>foo</literal> and <literal>bar</literal> in
+ <classname>Demo</classname>, and prints out information garnered from
+ <literal>thisJoinPoint</literal> to the console. </para>
+
+ <sect4>
+ <title>Defining the scope of a pointcut</title>
+
+ <para>The pointcut <function>goCut</function> is defined as
+ <literal><![CDATA[cflow(this(Demo)) && execution(void
+ go())]]></literal> so that only executions made in the control
+ flow of <literal>Demo.go</literal> are intercepted. The control
+ flow from the method <literal>go</literal> includes the execution of
+ <literal>go</literal> itself, so the definition of the around
+ advice includes <literal>!execution(* go())</literal> to exclude it
+ from the set of executions advised. </para>
+ </sect4>
+
+ <sect4>
+ <title>Printing the class and method name</title>
+
+ <para>The name of the method and that method's defining class are
+ available as parts of the <ulink
+ url="../api/org/aspectj/lang/Signature.html">Signature</ulink>,
+ found using the method <literal>getSignature</literal> of either
+ <literal>thisJoinPoint</literal> or
+ <literal>thisJoinPointStaticPart</literal>. </para>
+
+<programlisting><![CDATA[
+aspect GetInfo {
+
+ static final void println(String s){ System.out.println(s); }
+
+ pointcut goCut(): cflow(this(Demo) && execution(void go()));
+
+ pointcut demoExecs(): within(Demo) && execution(* *(..));
+
+ Object around(): demoExecs() && !execution(* go()) && goCut() {
+ println("Intercepted message: " +
+ thisJoinPointStaticPart.getSignature().getName());
+ println("in class: " +
+ thisJoinPointStaticPart.getSignature().getDeclaringType().getName());
+ printParameters(thisJoinPoint);
+ println("Running original method: \n" );
+ Object result = proceed();
+ println(" result: " + result );
+ return result;
+ }
+
+ static private void printParameters(JoinPoint jp) {
+ println("Arguments: " );
+ Object[] args = jp.getArgs();
+ String[] names = ((CodeSignature)jp.getSignature()).getParameterNames();
+ Class[] types = ((CodeSignature)jp.getSignature()).getParameterTypes();
+ for (int i = 0; i < args.length; i++) {
+ println(" " + i + ". " + names[i] +
+ " : " + types[i].getName() +
+ " = " + args[i]);
+ }
+ }
+}
+]]></programlisting>
+ </sect4>
+
+ <sect4>
+ <title>Printing the parameters</title>
+
+ <para>
+ The static portions of the parameter details, the name and
+ types of the parameters, can be accessed through the <ulink
+ url="../api/org/aspectj/lang/reflect/CodeSignature.html"><literal>CodeSignature</literal></ulink>
+ associated with the join point. All execution join points have code
+ signatures, so the cast to <literal>CodeSignature</literal>
+ cannot fail. </para>
+
+ <para>
+ The dynamic portions of the parameter details, the actual
+ values of the parameters, are accessed directly from the execution
+ join point object. </para>
+ </sect4>
+ </sect3>
+ </sect2>
+
+ <sect2 id="sec:RolesAndViews">
+ <title>Roles and Views Using Introduction</title>
+ <titleabbrev id="sec:RolesAndViews:title">Roles and Views Using
+ Introduction</titleabbrev>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/introduction</filename>.)</para>
+
+ <para>Like advice, pieces of introduction are members of an aspect. They
+ define new members that act as if they were defined on another
+ class. Unlike advice, introduction affects not only the behavior of the
+ application, but also the structural relationship between an
+ application's classes. </para>
+
+ <para>This is crucial: Affecting the class structure of an application at
+ makes these modifications available to other components of the
+ application.</para>
+
+ <para>Introduction modifies a class by adding or changing</para>
+ <itemizedlist spacing="compact">
+ <listitem>member fields</listitem>
+ <listitem>member methods</listitem>
+ <listitem>nested classes</listitem>
+ </itemizedlist>
+
+ <para>and by making the class</para>
+
+ <itemizedlist spacing="compact">
+ <listitem>implement interfaces</listitem>
+ <listitem>extend classes</listitem>
+ </itemizedlist>
+
+ <para>
+ This example provides three illustrations of the use of introduction to
+ encapsulate roles or views of a class. The class we will be introducing
+ into, <classname>Point</classname>, is a simple class with rectangular
+ and polar coordinates. Our introduction will make the class
+ <classname>Point</classname>, in turn, cloneable, hashable, and
+ comparable. These facilities are provided by introduction forms without
+ having to modify the class <classname>Point</classname>.
+ </para>
+
+ <sect3>
+ <title>The class <classname>Point</classname></title>
+
+ <para>The class <classname>Point</classname> defines geometric points
+ whose interface includes polar and rectangular coordinates, plus some
+ simple operations to relocate points. <classname>Point</classname>'s
+ implementation has attributes for both its polar and rectangular
+ coordinates, plus flags to indicate which currently reflect the
+ position of the point. Some operations cause the polar coordinates to
+ be updated from the rectangular, and some have the opposite effect.
+ This implementation, which is in intended to give the minimum number
+ of conversions between coordinate systems, has the property that not
+ all the attributes stored in a <classname>Point</classname> object
+ are necessary to give a canonical representation such as might be
+ used for storing, comparing, cloning or making hash codes from
+ points. Thus the aspects, though simple, are not totally trivial.
+ </para>
+
+ <para>
+ The diagram below gives an overview of the aspects and their
+ interaction with the class <classname>Point</classname>.</para>
+
+ <para>
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="aspects.gif"/>
+ </imageobject>
+ </inlinemediaobject>
+ </para>
+ <para></para>
+
+ </sect3>
+
+ <sect3>
+ <title>Making <classname>Point</classname>s Cloneable &mdash; The Aspect
+ <classname>CloneablePoint</classname></title>
+
+ <para>This first example demonstrates the introduction of a interface
+ (<classname>Cloneable</classname>) and a method
+ (<function>clone</function>) into the class
+ <classname>Point</classname>. In Java, all objects inherit the method
+ <literal>clone</literal> from the class
+ <classname>Object</classname>, but an object is not cloneable unless
+ its class also implements the interface
+ <classname>Cloneable</classname>. In addition, classes frequently
+ have requirements over and above the simple bit-for-bit copying that
+ <literal>Object.clone</literal> does. In our case, we want to update
+ a <classname>Point</classname>'s coordinate systems before we
+ actually clone the <classname>Point</classname>. So we have to
+ override <literal>Object.clone</literal> with a new method that does
+ what we want. </para>
+
+ <para>The <classname>CloneablePoint</classname> aspect uses the
+ <literal>declare parents</literal> form to introduce the interface
+ <classname>Cloneable</classname> into the class
+ <classname>Point</classname>. It then defines a method,
+ <literal>Point.clone</literal>, which overrides the method
+ <function>clone</function> that was inherited from
+ <classname>Object</classname>. <function>Point.clone</function>
+ updates the <classname>Point</classname>'s coordinate systems before
+ invoking its superclass' <function>clone</function> method.</para>
+
+ <programlisting><![CDATA[
+public aspect CloneablePoint {
+
+ declare parents: Point implements Cloneable;
+
+ public Object Point.clone() throws CloneNotSupportedException {
+ // we choose to bring all fields up to date before cloning.
+ makeRectangular();
+ makePolar();
+ return super.clone();
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ Point p2 = null;
+
+ p1.setPolar(Math.PI, 1.0);
+ try {
+ p2 = (Point)p1.clone();
+ } catch (CloneNotSupportedException e) {}
+ System.out.println("p1 =" + p1 );
+ System.out.println("p2 =" + p2 );
+
+ p1.rotate(Math.PI / -2);
+ System.out.println("p1 =" + p1 );
+ System.out.println("p2 =" + p2 );
+ }
+}
+]]></programlisting>
+
+ <para>Note that since aspects define types just as classes define
+ types, we can define a <function>main</function> method that is
+ invocable from the command line to use as a test method.</para>
+ </sect3>
+
+ <sect3>
+ <title>Making <classname>Point</classname>s Comparable &mdash; The
+ Aspect <classname>ComparablePoint</classname></title>
+
+ <para>This second example introduces another interface and
+ method into the class <classname>Point</classname>.</para>
+
+ <para>The interface <classname>Comparable</classname> defines the
+ single method <literal>compareTo</literal> which can be use to define
+ a natural ordering relation among the objects of a class that
+ implement it. </para>
+
+ <para>The aspect <classname>ComparablePoint</classname> introduces
+ implements <classname>Comparable</classname> into
+ <classname>Point</classname> along with a
+ <literal>compareTo</literal> method that can be used to compare
+ <classname>Point</classname>s. A <classname>Point</classname>
+ <literal>p1</literal> is said to be less than
+ another <classname>Point</classname><literal> p2</literal> if
+ <literal>p1</literal> is closer to the origin. </para>
+
+ <programlisting><![CDATA[
+public aspect ComparablePoint {
+
+ declare parents: Point implements Comparable;
+
+ public int Point.compareTo(Object o) {
+ return (int) (this.getRho() - ((Point)o).getRho());
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ Point p2 = new Point();
+
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.setRectangular(2,5);
+ p2.setRectangular(2,5);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p2.setRectangular(3,6);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.setPolar(Math.PI, 4);
+ p2.setPolar(Math.PI, 4);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.rotate(Math.PI / 4.0);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+
+ p1.offset(1,1);
+ System.out.println("p1 =?= p2 :" + p1.compareTo(p2));
+ }
+}]]></programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Making <classname>Point</classname>s Hashable &mdash; The Aspect
+ <classname>HashablePoint</classname></title>
+
+ <para>The third aspect overrides two previously defined methods to
+ give to <classname>Point</classname> the hashing behavior we
+ want.</para>
+
+ <para>The method <literal>Object.hashCode</literal> returns an unique
+ integer, suitable for use as a hash table key. Different
+ implementations are allowed return different integers, but must
+ return distinct integers for distinct objects, and the same integer
+ for objects that test equal. But since the default implementation
+ of <literal>Object.equal</literal> returns <literal>true</literal>
+ only when two objects are identical, we need to redefine both
+ <function>equals</function> and <function>hashCode</function> to work
+ correctly with objects of type <classname>Point</classname>. For
+ example, we want two <classname>Point</classname> objects to test
+ equal when they have the same <literal>x</literal> and
+ <literal>y</literal> values, or the same <literal>rho</literal> and
+ <literal>theta</literal> values, not just when they refer to the same
+ object. We do this by overriding the methods
+ <literal>equals</literal> and <literal>hashCode</literal> in the
+ class <classname>Point</classname>. </para>
+
+ <para>The class <classname>HashablePoint</classname> introduces the
+ methods <literal>hashCode</literal> and <literal>equals</literal>
+ into the class <classname>Point</classname>. These methods use
+ <classname>Point</classname>'s rectangular coordinates to generate a
+ hash code and to test for equality. The <literal>x</literal> and
+ <literal>y</literal> coordinates are obtained using the appropriate
+ get methods, which ensure the rectangular coordinates are up-to-date
+ before returning their values. </para>
+
+ <programlisting><![CDATA[
+public aspect HashablePoint {
+
+ public int Point.hashCode() {
+ return (int) (getX() + getY() % Integer.MAX_VALUE);
+ }
+
+ public boolean Point.equals(Object o) {
+ if (o == this) { return true; }
+ if (!(o instanceof Point)) { return false; }
+ Point other = (Point)o;
+ return (getX() == other.getX()) && (getY() == other.getY());
+ }
+
+ public static void main(String[] args) {
+ Hashtable h = new Hashtable();
+ Point p1 = new Point();
+
+ p1.setRectangular(10, 10);
+ Point p2 = new Point();
+
+ p2.setRectangular(10, 10);
+
+ System.out.println("p1 = " + p1);
+ System.out.println("p2 = " + p2);
+ System.out.println("p1.hashCode() = " + p1.hashCode());
+ System.out.println("p2.hashCode() = " + p2.hashCode());
+
+ h.put(p1, "P1");
+ System.out.println("Got: " + h.get(p2));
+ }
+}
+]]></programlisting>
+
+ <para> Again, we supply a <literal>main</literal> method in the aspect
+ for testing.
+ </para>
+
+ </sect3>
+
+ </sect2>
+
+ </sect1>
+
+<!-- ============================================================ -->
+<!-- ============================================================ -->
+
+ <sect1>
+ <title>Development Aspects</title>
+
+ <sect2>
+ <title>Tracing Aspects</title>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/tracing</filename>.)
+ </para>
+
+ <sect3>
+ <title>Overview</title>
+
+ <para>
+ Writing a class that provides tracing functionality is easy: a couple
+ of functions, a boolean flag for turning tracing on and off, a choice
+ for an output stream, maybe some code for formatting the output---these
+ are all elements that <classname>Trace</classname> classes have been
+ known to have. <classname>Trace</classname> classes may be highly
+ sophisticated, too, if the task of tracing the execution of a program
+ demands so.
+ </para>
+
+ <para>
+ But developing the support for tracing is just one part of the effort
+ of inserting tracing into a program, and, most likely, not the biggest
+ part. The other part of the effort is calling the tracing functions at
+ appropriate times. In large systems, this interaction with the tracing
+ support can be overwhelming. Plus, tracing is one of those things that
+ slows the system down, so these calls should often be pulled out of the
+ system before the product is shipped. For these reasons, it is not
+ unusual for developers to write ad-hoc scripting programs that rewrite
+ the source code by inserting/deleting trace calls before and after the
+ method bodies.
+ </para>
+
+ <para>
+ AspectJ can be used for some of these tracing concerns in a less ad-hoc
+ way. Tracing can be seen as a concern that crosscuts the entire system
+ and as such is amenable to encapsulation in an aspect. In addition, it
+ is fairly independent of what the system is doing. Therefore tracing is
+ one of those kind of system aspects that can potentially be plugged in
+ and unplugged without any side-effects in the basic functionality of
+ the system.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>An Example Application</title>
+
+ <para>
+ Throughout this example we will use a simple application that contains
+ only four classes. The application is about shapes. The
+ <classname>TwoDShape</classname> class is the root of the shape
+ hierarchy:
+ </para>
+
+<programlisting><![CDATA[
+public abstract class TwoDShape {
+ protected double x, y;
+ protected TwoDShape(double x, double y) {
+ this.x = x; this.y = y;
+ }
+ public double getX() { return x; }
+ public double getY() { return y; }
+ public double distance(TwoDShape s) {
+ double dx = Math.abs(s.getX() - x);
+ double dy = Math.abs(s.getY() - y);
+ return Math.sqrt(dx*dx + dy*dy);
+ }
+ public abstract double perimeter();
+ public abstract double area();
+ public String toString() {
+ return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");
+ }
+}
+]]></programlisting>
+
+ <para>
+ <classname>TwoDShape</classname> has two subclasses,
+ <classname>Circle</classname> and <classname>Square</classname>:
+ </para>
+
+<programlisting><![CDATA[
+public class Circle extends TwoDShape {
+ protected double r;
+ public Circle(double x, double y, double r) {
+ super(x, y); this.r = r;
+ }
+ public Circle(double x, double y) { this( x, y, 1.0); }
+ public Circle(double r) { this(0.0, 0.0, r); }
+ public Circle() { this(0.0, 0.0, 1.0); }
+ public double perimeter() {
+ return 2 * Math.PI * r;
+ }
+ public double area() {
+ return Math.PI * r*r;
+ }
+ public String toString() {
+ return ("Circle radius = " + String.valueOf(r) + super.toString());
+ }
+}
+]]></programlisting>
+
+<programlisting><![CDATA[
+public class Square extends TwoDShape {
+ protected double s; // side
+ public Square(double x, double y, double s) {
+ super(x, y); this.s = s;
+ }
+ public Square(double x, double y) { this( x, y, 1.0); }
+ public Square(double s) { this(0.0, 0.0, s); }
+ public Square() { this(0.0, 0.0, 1.0); }
+ public double perimeter() {
+ return 4 * s;
+ }
+ public double area() {
+ return s*s;
+ }
+ public String toString() {
+ return ("Square side = " + String.valueOf(s) + super.toString());
+ }
+}
+]]></programlisting>
+
+ <para>
+ To run this application, compile the classes. You can do it with or
+ without ajc, the AspectJ compiler. If you've installed AspectJ, go to
+ the directory
+ <filename><replaceable>InstallDir</replaceable>/examples</filename> and
+ type:
+ </para>
+
+<programlisting>
+ajc -argfile tracing/notrace.lst
+</programlisting>
+
+ <para>To run the program, type</para>
+
+<programlisting>
+java tracing.ExampleMain
+</programlisting>
+
+ <para>(we don't need anything special on the classpath since this is pure
+ Java code). You should see the following output:</para>
+
+<programlisting><![CDATA[
+c1.perimeter() = 12.566370614359172
+c1.area() = 12.566370614359172
+s1.perimeter() = 4.0
+s1.area() = 1.0
+c2.distance(c1) = 4.242640687119285
+s1.distance(c1) = 2.23606797749979
+s1.toString(): Square side = 1.0 @ (1.0, 2.0)
+]]></programlisting>
+
+ </sect3>
+ <sect3>
+ <title>Tracing&mdash;Version 1</title>
+
+ <para>
+ In a first attempt to insert tracing in this application, we will start
+ by writing a <classname>Trace</classname> class that is exactly what we
+ would write if we didn't have aspects. The implementation is in
+ <filename>version1/Trace.java</filename>. Its public interface is:
+ </para>
+
+<programlisting><![CDATA[
+public class Trace {
+ public static int TRACELEVEL = 0;
+ public static void initStream(PrintStream s) {...}
+ public static void traceEntry(String str) {...}
+ public static void traceExit(String str) {...}
+}
+]]></programlisting>
+
+ <para>
+ If we didn't have AspectJ, we would have to insert calls to
+ <literal>traceEntry</literal> and <literal>traceExit</literal> in all
+ methods and constructors we wanted to trace, and to initialize
+ <literal>TRACELEVEL</literal> and the stream. If we wanted to trace all
+ the methods and constructors in our example, that would amount to
+ around 40 calls, and we would hope we had not forgotten any method. But
+ we can do that more consistently and reliably with the following
+ aspect (found in <filename>version1/TraceMyClasses.java</filename>):
+ </para>
+
+<programlisting><![CDATA[
+aspect TraceMyClasses {
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+ pointcut myConstructor(): myClass() && execution(new(..));
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ before (): myConstructor() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ before (): myMethod() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+}]]></programlisting>
+
+ <para>
+ This aspect performs the tracing calls at appropriate times. According
+ to this aspect, tracing is performed at the entrance and exit of every
+ method and constructor defined within the shape hierarchy.
+ </para>
+
+ <para>
+ What is printed at before and after each of the traced
+ join points is the signature of the method executing. Since the
+ signature is static information, we can get it through
+ <literal>thisJoinPointStaticPart</literal>.
+ </para>
+
+ <para>
+ To run this version of tracing, go to the directory
+ <filename><replaceable>InstallDir</replaceable>/examples</filename> and
+ type:
+ </para>
+
+<programlisting><![CDATA[
+ ajc -argfile tracing/tracev1.lst
+]]></programlisting>
+
+ <para>
+ Running the main method of
+ <classname>tracing.version1.TraceMyClasses</classname> should produce
+ the output:
+ </para>
+
+<programlisting><![CDATA[
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Circle(double, double, double)
+ <-- tracing.Circle(double, double, double)
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Circle(double, double, double)
+ <-- tracing.Circle(double, double, double)
+ --> tracing.Circle(double)
+ <-- tracing.Circle(double)
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Square(double, double, double)
+ <-- tracing.Square(double, double, double)
+ --> tracing.Square(double, double)
+ <-- tracing.Square(double, double)
+ --> double tracing.Circle.perimeter()
+ <-- double tracing.Circle.perimeter()
+c1.perimeter() = 12.566370614359172
+ --> double tracing.Circle.area()
+ <-- double tracing.Circle.area()
+c1.area() = 12.566370614359172
+ --> double tracing.Square.perimeter()
+ <-- double tracing.Square.perimeter()
+s1.perimeter() = 4.0
+ --> double tracing.Square.area()
+ <-- double tracing.Square.area()
+s1.area() = 1.0
+ --> double tracing.TwoDShape.distance(TwoDShape)
+ --> double tracing.TwoDShape.getX()
+ <-- double tracing.TwoDShape.getX()
+ --> double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.distance(TwoDShape)
+c2.distance(c1) = 4.242640687119285
+ --> double tracing.TwoDShape.distance(TwoDShape)
+ --> double tracing.TwoDShape.getX()
+ <-- double tracing.TwoDShape.getX()
+ --> double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.distance(TwoDShape)
+s1.distance(c1) = 2.23606797749979
+ --> String tracing.Square.toString()
+ --> String tracing.TwoDShape.toString()
+ <-- String tracing.TwoDShape.toString()
+ <-- String tracing.Square.toString()
+s1.toString(): Square side = 1.0 @ (1.0, 2.0)
+]]></programlisting>
+
+ <para>
+ When <filename>TraceMyClasses.java</filename> is not provided to
+ <command>ajc</command>, the aspect does not have any affect on the
+ system and the tracing is unplugged.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Tracing&mdash;Version 2</title>
+
+ <para>
+ Another way to accomplish the same thing would be to write a reusable
+ tracing aspect that can be used not only for these application classes,
+ but for any class. One way to do this is to merge the tracing
+ functionality of <literal>Trace&mdash;version1</literal> with the
+ crosscutting support of
+ <literal>TraceMyClasses&mdash;version1</literal>. We end up with a
+ <literal>Trace</literal> aspect (found in
+ <filename>version2/Trace.java</filename>) with the following public
+ interface
+ </para>
+
+<programlisting><![CDATA[
+abstract aspect Trace {
+
+ public static int TRACELEVEL = 2;
+ public static void initStream(PrintStream s) {...}
+ protected static void traceEntry(String str) {...}
+ protected static void traceExit(String str) {...}
+ abstract pointcut myClass();
+}
+]]></programlisting>
+
+ <para>
+ In order to use it, we need to define our own subclass that knows about
+ our application classes, in <filename>version2/TraceMyClasses.java</filename>:
+ </para>
+
+<programlisting><![CDATA[
+public aspect TraceMyClasses extends Trace {
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
+]]></programlisting>
+
+ <para>
+ Notice that we've simply made the pointcut <literal>classes</literal>,
+ that was an abstract pointcut in the super-aspect, concrete. To run
+ this version of tracing, go to the directory
+ <filename>examples</filename> and type:
+ </para>
+
+<programlisting><![CDATA[
+ ajc -argfile tracing/tracev2.lst
+]]></programlisting>
+
+ <para>
+ The file tracev2.lst lists the application classes as well as this
+ version of the files Trace.java and TraceMyClasses.java. Running the
+ main method of <classname>tracing.version2.TraceMyClasses</classname>
+ should output exactly the same trace information as that from version
+ 1.
+ </para>
+
+ <para>
+ The entire implementation of the new <classname>Trace</classname> class
+ is:
+ </para>
+
+<programlisting><![CDATA[
+abstract aspect Trace {
+
+ // implementation part
+
+ public static int TRACELEVEL = 2;
+ protected static PrintStream stream = System.err;
+ protected static int callDepth = 0;
+
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+ protected static void traceEntry(String str) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str);
+ }
+ protected static void traceExit(String str) {
+ if (TRACELEVEL == 0) return;
+ printExiting(str);
+ if (TRACELEVEL == 2) callDepth--;
+ }
+ private static void printEntering(String str) {
+ printIndent();
+ stream.println("--> " + str);
+ }
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("<-- " + str);
+ }
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+
+ // protocol part
+
+ abstract pointcut myClass();
+
+ pointcut myConstructor(): myClass() && execution(new(..));
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ before(): myConstructor() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ before(): myMethod() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+}
+]]></programlisting>
+
+ <para>
+ This version differs from version 1 in several subtle ways. The first
+ thing to notice is that this <classname>Trace</classname> class merges
+ the functional part of tracing with the crosscutting of the tracing
+ calls. That is, in version 1, there was a sharp separation between the
+ tracing support (the class <classname>Trace</classname>) and the
+ crosscutting usage of it (by the class
+ <classname>TraceMyClasses</classname>). In this version those two
+ things are merged. That's why the description of this class explicitly
+ says that "Trace messages are printed before and after constructors and
+ methods are," which is what we wanted in the first place. That is, the
+ placement of the calls, in this version, is established by the aspect
+ class itself, leaving less opportunity for misplacing calls.</para>
+
+ <para>
+ A consequence of this is that there is no need for providing traceEntry
+ and traceExit as public operations of this class. You can see that they
+ were classified as protected. They are supposed to be internal
+ implementation details of the advice.
+ </para>
+
+ <para>
+ The key piece of this aspect is the abstract pointcut classes that
+ serves as the base for the definition of the pointcuts constructors and
+ methods. Even though <classname>classes</classname> is abstract, and
+ therefore no concrete classes are mentioned, we can put advice on it,
+ as well as on the pointcuts that are based on it. The idea is "we don't
+ know exactly what the pointcut will be, but when we do, here's what we
+ want to do with it." In some ways, abstract pointcuts are similar to
+ abstract methods. Abstract methods don't provide the implementation,
+ but you know that the concrete subclasses will, so you can invoke those
+ methods.
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+<!-- ============================================================ -->
+<!-- ============================================================ -->
+
+ <sect1>
+ <title>Production Aspects</title>
+
+ <!-- ==================== -->
+
+ <sect2><!-- A Bean Aspect -->
+ <title>A Bean Aspect</title>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/bean</filename>.)
+ </para>
+
+ <para>
+ This example examines an aspect that makes Point objects into a Java beans
+ with bound properties. </para>
+
+ <sect3>
+ <title>Introduction</title>
+ <para>
+ Java beans are reusable software components that can be visually
+ manipulated in a builder tool. The requirements for an object to be a
+ bean are few. Beans must define a no-argument constructor and must be
+ either <classname>Serializable</classname> or
+ <classname>Externalizable</classname>. Any properties of the object
+ that are to be treated as bean properties should be indicated by the
+ presence of appropriate <literal>get</literal> and
+ <literal>set</literal> methods whose names are
+ <literal>get</literal><emphasis>property</emphasis> and
+ <literal>set </literal><emphasis>property</emphasis>
+ where <emphasis>property</emphasis> is the name of a field in the bean
+ class. Some bean properties, known as bound properties, fire events
+ whenever their values change so that any registered listeners (such as,
+ other beans) will be informed of those changes. Making a bound property
+ involves keeping a list of registered listeners, and creating and
+ dispatching event objects in methods that change the property values,
+ such as set<emphasis>property</emphasis> methods.</para>
+
+ <para>
+ <classname>Point</classname> is a simple class representing points with
+ rectangular coordinates. <classname>Point</classname> does not know
+ anything about being a bean: there are set methods for
+ <literal>x</literal> and <literal>y</literal> but they do not fire
+ events, and the class is not serializable. Bound is an aspect that
+ makes <classname>Point</classname> a serializable class and makes its
+ <literal>get</literal> and <literal>set</literal> methods support the
+ bound property protocol.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>The Class <classname>Point</classname></title>
+
+ <para>
+ The class <classname>Point</classname> is a very simple class with
+ trivial getters and setters, and a simple vector offset method.
+ </para>
+
+ <programlisting><![CDATA[
+class Point {
+
+ protected int x = 0;
+ protected int y = 0;
+
+ public int getX() {
+ return x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setRectangular(int newX, int newY) {
+ setX(newX);
+ setY(newY);
+ }
+
+ public void setX(int newX) {
+ x = newX;
+ }
+
+ public void setY(int newY) {
+ y = newY;
+ }
+
+ public void offset(int deltaX, int deltaY) {
+ setRectangular(x + deltaX, y + deltaY);
+ }
+
+ public String toString() {
+ return "(" + getX() + ", " + getY() + ")" ;
+ }
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Aspect <classname>BoundPoint</classname></title>
+
+ <para>
+ The aspect <classname>BoundPoint</classname> adds "beanness" to
+ <classname>Point</classname> objects. The first thing it does is
+ privately introduce a reference to an instance of
+ <classname>PropertyChangeSupport</classname> into all
+ <classname>Point</classname> objects. The property change
+ support object must be constructed with a reference to the bean for
+ which it is providing support, so it is initialized by passing it this,
+ an instance of <classname>Point</classname>. The support field is
+ privately introduced, so only the code in the aspect can refer to it.
+ </para>
+
+ <para>
+ Methods for registering and managing listeners for property change
+ events are introduced into <classname>Point</classname> by the
+ introductions. These methods delegate the work to the
+ property change support object.
+ </para>
+
+ <para>
+ The introduction also makes <classname>Point</classname> implement the
+ <classname>Serializable</classname> interface. Implementing
+ <classname>Serializable</classname> does not require any methods to be
+ implemented. Serialization for <classname>Point</classname> objects is
+ provided by the default serialization method.
+ </para>
+
+ <para>
+ The pointcut <function>setters</function> names the
+ <literal>set</literal> methods: reception by a
+ <classname>Point</classname> object of any method whose name begins
+ with '<literal>set</literal>' and takes one parameter. The around
+ advice on <literal>setters()</literal> stores the values
+ of the <literal>X</literal> and <literal>Y</literal> properties, calls
+ the original <literal>set</literal> method and then fires the
+ appropriate property change event according to which set method was
+ called. Note that the call to the method proceed needs to pass along
+ the <literal>Point p</literal>. The rule of thumb is that context that
+ an around advice exposes must be passed forward to continue.
+ </para>
+
+<programlisting><![CDATA[
+aspect BoundPoint {
+ private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
+
+ public void Point.addPropertyChangeListener(PropertyChangeListener listener){
+ support.addPropertyChangeListener(listener);
+ }
+
+ public void Point.addPropertyChangeListener(String propertyName,
+ PropertyChangeListener listener){
+
+ support.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void Point.removePropertyChangeListener(String propertyName,
+ PropertyChangeListener listener) {
+ support.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public void Point.removePropertyChangeListener(PropertyChangeListener listener) {
+ support.removePropertyChangeListener(listener);
+ }
+
+ public void Point.hasListeners(String propertyName) {
+ support.hasListeners(propertyName);
+ }
+
+ declare parents: Point implements Serializable;
+
+ pointcut setter(Point p): call(void Point.set*(*)) && target(p);
+
+ void around(Point p): setter(p) {
+ String propertyName =
+ thisJoinPointStaticPart.getSignature().getName().substring("set".length());
+ int oldX = p.getX();
+ int oldY = p.getY();
+ proceed(p);
+ if (propertyName.equals("X")){
+ firePropertyChange(p, propertyName, oldX, p.getX());
+ } else {
+ firePropertyChange(p, propertyName, oldY, p.getY());
+ }
+ }
+
+ void firePropertyChange(Point p,
+ String property,
+ double oldval,
+ double newval) {
+ p.support.firePropertyChange(property,
+ new Double(oldval),
+ new Double(newval));
+ }
+}
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Test Program</title>
+
+ <para>
+ The test program registers itself as a property change listener to a
+ <literal>Point</literal> object that it creates and then performs
+ simple manipulation of that point: calling its set methods and the
+ offset method. Then it serializes the point and writes it to a file and
+ then reads it back. The result of saving and restoring the point is that
+ a new point is created.
+ </para>
+
+<programlisting><![CDATA[
+ class Demo implements PropertyChangeListener {
+
+ static final String fileName = "test.tmp";
+
+ public void propertyChange(PropertyChangeEvent e){
+ System.out.println("Property " + e.getPropertyName() + " changed from " +
+ e.getOldValue() + " to " + e.getNewValue() );
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ p1.addPropertyChangeListener(new Demo());
+ System.out.println("p1 =" + p1);
+ p1.setRectangular(5,2);
+ System.out.println("p1 =" + p1);
+ p1.setX( 6 );
+ p1.setY( 3 );
+ System.out.println("p1 =" + p1);
+ p1.offset(6,4);
+ System.out.println("p1 =" + p1);
+ save(p1, fileName);
+ Point p2 = (Point) restore(fileName);
+ System.out.println("Had: " + p1);
+ System.out.println("Got: " + p2);
+ }
+ ...
+ }
+]]></programlisting>
+
+ </sect3>
+ <sect3>
+ <title>Compiling and Running the Example</title>
+ <para>To compile and run this example, go to the examples directory and type:
+ </para>
+
+<programlisting><![CDATA[
+ajc -argfile bean/files.lst
+java bean.Demo
+]]></programlisting>
+
+ </sect3>
+ </sect2>
+
+ <!-- ==================== -->
+
+ <sect2><!-- The Subject/Observer Protocol -->
+ <title>The Subject/Observer Protocol</title>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/observer</filename>.)
+ </para>
+
+ <para>
+ This demo illustrates how the Subject/Observer design pattern can be
+ coded with aspects. </para>
+
+ <sect3>
+ <title>Overview</title>
+ <para>
+ The demo consists of the following: A colored label is a renderable
+ object that has a color that cycles through a set of colors, and a
+ number that records the number of cycles it has been through. A button
+ is an action item that records when it is clicked.
+ </para>
+
+ <para>
+ With these two kinds of objects, we can build up a Subject/Observer
+ relationship in which colored labels observe the clicks of buttons;
+ that is, where colored labels are the observers and buttons are the
+ subjects.
+ </para>
+
+ <para>
+ The demo is designed and implemented using the Subject/Observer design
+ pattern. The remainder of this example explains the classes and aspects
+ of this demo, and tells you how to run it.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Generic Components</title>
+
+ <para>
+ The generic parts of the protocol are the interfaces
+ <classname>Subject</classname> and <classname>Observer</classname>, and
+ the abstract aspect <classname>SubjectObserverProtocol</classname>. The
+ <classname>Subject</classname> interface is simple, containing methods
+ to add, remove, and view <classname>Observer</classname> objects, and a
+ method for getting data about state changes:
+ </para>
+
+<programlisting><![CDATA[
+ interface Subject {
+ void addObserver(Observer obs);
+ void removeObserver(Observer obs);
+ Vector getObservers();
+ Object getData();
+ }
+]]></programlisting>
+
+ <para> The <classname>Observer</classname> interface is just as simple,
+ with methods to set and get <classname>Subject</classname> objects, and
+ a method to call when the subject gets updated.
+ </para>
+
+<programlisting><![CDATA[
+ interface Observer {
+ void setSubject(Subject s);
+ Subject getSubject();
+ void update();
+ }
+]]></programlisting>
+
+ <para>
+ The <classname>SubjectObserverProtocol</classname> aspect contains
+ within it all of the generic parts of the protocol, namely, how to fire
+ the <classname>Observer</classname> objects' update methods when some
+ state changes in a subject.
+ </para>
+
+<programlisting><![CDATA[
+ abstract aspect SubjectObserverProtocol {
+
+ abstract pointcut stateChanges(Subject s);
+
+ after(Subject s): stateChanges(s) {
+ for (int i = 0; i < s.getObservers().size(); i++) {
+ ((Observer)s.getObservers().elementAt(i)).update();
+ }
+ }
+
+ private Vector Subject.observers = new Vector();
+ public void Subject.addObserver(Observer obs) {
+ observers.addElement(obs);
+ obs.setSubject(this);
+ }
+ public void Subject.removeObserver(Observer obs) {
+ observers.removeElement(obs);
+ obs.setSubject(null);
+ }
+ public Vector Subject.getObservers() { return observers; }
+
+ private Subject Observer.subject = null;
+ public void Observer.setSubject(Subject s) { subject = s; }
+ public Subject Observer.getSubject() { return subject; }
+
+ }
+]]></programlisting>
+
+ <para>
+ Note that this aspect does three things. It define an abstract pointcut
+ that extending aspects can override. It defines advice that should run
+ after the join points of the pointcut. And it introduces state and
+ behavior onto the <classname>Subject</classname> and
+ <classname>Observer</classname> interfaces.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Application Classes</title>
+
+ <para> <classname>Button</classname> objects extend
+ <classname>java.awt.Button</classname>, and all they do is make sure
+ the <literal>void click()</literal> method is called whenever a button
+ is clicked.
+ </para>
+
+<programlisting><![CDATA[
+ class Button extends java.awt.Button {
+
+ static final Color defaultBackgroundColor = Color.gray;
+ static final Color defaultForegroundColor = Color.black;
+ static final String defaultText = "cycle color";
+
+ Button(Display display) {
+ super();
+ setLabel(defaultText);
+ setBackground(defaultBackgroundColor);
+ setForeground(defaultForegroundColor);
+ addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ Button.this.click();
+ }
+ });
+ display.addToFrame(this);
+ }
+
+ public void click() {}
+
+ }
+]]></programlisting>
+
+ <para>
+ Note that this class knows nothing about being a Subject.
+ </para>
+ <para>
+ ColorLabel objects are labels that support the void colorCycle()
+ method. Again, they know nothing about being an observer.
+ </para>
+
+<programlisting><![CDATA[
+ class ColorLabel extends Label {
+
+ ColorLabel(Display display) {
+ super();
+ display.addToFrame(this);
+ }
+
+ final static Color[] colors = {Color.red, Color.blue,
+ Color.green, Color.magenta};
+ private int colorIndex = 0;
+ private int cycleCount = 0;
+ void colorCycle() {
+ cycleCount++;
+ colorIndex = (colorIndex + 1) % colors.length;
+ setBackground(colors[colorIndex]);
+ setText("" + cycleCount);
+ }
+ }
+]]></programlisting>
+
+ <para>
+ Finally, the <classname>SubjectObserverProtocolImpl</classname>
+ implements the subject/observer protocol, with
+ <classname>Button</classname> objects as subjects and
+ <classname>ColorLabel</classname> objects as observers:
+ </para>
+
+<programlisting><![CDATA[
+package observer;
+
+import java.util.Vector;
+
+aspect SubjectObserverProtocolImpl extends SubjectObserverProtocol {
+
+ declare parents: Button implements Subject;
+ public Object Button.getData() { return this; }
+
+ declare parents: ColorLabel implements Observer;
+ public void ColorLabel.update() {
+ colorCycle();
+ }
+
+ pointcut stateChanges(Subject s):
+ target(s) &&
+ call(void Button.click());
+
+}]]></programlisting>
+
+ <para>
+ It does this by introducing the appropriate interfaces onto the
+ <classname>Button</classname> and <classname>ColorLabel</classname>
+ classes, making sure the methods required by the interfaces are
+ implemented, and providing a definition for the
+ <literal>stateChanges</literal> pointcut. Now, every time a
+ <classname>Button</classname> is clicked, all
+ <classname>ColorLabel</classname> objects observing that button will
+ <literal>colorCycle</literal>.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Compiling and Running</title>
+
+ <para> <classname>Demo</classname> is the top class that starts this
+ demo. It instantiates a two buttons and three observers and links them
+ together as subjects and observers. So to run the demo, go to the
+ <filename>examples</filename> directory and type:
+ </para>
+
+<programlisting><![CDATA[
+ ajc -argfile observer/files.lst
+ java observer.Demo
+]]></programlisting>
+
+ </sect3>
+ </sect2>
+
+ <!-- ==================== -->
+
+ <sect2>
+ <title>A Simple Telecom Simulation</title>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/telecom</filename>.)
+ </para>
+
+ <para>
+ This example illustrates some ways that dependent concerns can be encoded
+ with aspects. It uses an example system comprising a simple model of
+ telephone connections to which timing and billing features are added
+ using aspects, where the billing feature depends upon the timing feature.
+ </para>
+
+ <sect3>
+ <title>The Application</title>
+
+ <para>
+ The example application is a simple simulation of a telephony system in
+ which customers make, accept, merge and hang-up both local and long
+ distance calls. The application architecture is in three layers.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The basic objects provide basic functionality to simulate
+ customers, calls and connections (regular calls have one
+ connection, conference calls have more than one).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The timing feature is concerned with timing the connections and
+ keeping the total connection time per customer. Aspects are used to
+ add a timer to each connection and to manage the total time per
+ customer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ The billing feature is concerned with charging customers for the
+ calls they make. Aspects are used to calculate a charge per
+ connection and, upon termination of a connection, to add the charge
+ to the appropriate customer's bill. The billing aspect builds upon
+ the timing aspect: it uses a pointcut defined in Timing and it uses
+ the timers that are associated with connections.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The simulation of system has three configurations: basic, timing and
+ billing. Programs for the three configurations are in classes
+ <classname>BasicSimulation</classname>,
+ <classname>TimingSimulation</classname> and
+ <classname>BillingSimulation</classname>. These share a common
+ superclass <classname>AbstractSimulation</classname>, which defines the
+ method run with the simulation itself and the method wait used to
+ simulate elapsed time.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>The Basic Objects</title>
+
+ <para>
+ The telecom simulation comprises the classes
+ <classname>Customer</classname>, <classname>Call</classname> and the
+ abstract class <classname>Connection</classname> with its two concrete
+ subclasses <classname>Local</classname> and
+ <classname>LongDistance</classname>. Customers have a name and a
+ numeric area code. They also have methods for managing calls. Simple
+ calls are made between one customer (the caller) and another (the
+ receiver), a <classname>Connection</classname> object is used to
+ connect them. Conference calls between more than two customers will
+ involve more than one connection. A customer may be involved in many
+ calls at one time.
+ <inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="telecom.gif"/>
+ </imageobject>
+ </inlinemediaobject>
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>The Class <classname>Customer</classname></title>
+
+ <para>
+ <classname>Customer</classname> has methods <literal>call</literal>,
+ <literal>pickup</literal>, <literal>hangup</literal> and
+ <literal>merge</literal> for managing calls.
+ </para>
+
+<programlisting><![CDATA[
+public class Customer {
+
+ private String name;
+ private int areacode;
+ private Vector calls = new Vector();
+
+ protected void removeCall(Call c){
+ calls.removeElement(c);
+ }
+
+ protected void addCall(Call c){
+ calls.addElement(c);
+ }
+
+ public Customer(String name, int areacode) {
+ this.name = name;
+ this.areacode = areacode;
+ }
+
+ public String toString() {
+ return name + "(" + areacode + ")";
+ }
+
+ public int getAreacode(){
+ return areacode;
+ }
+
+ public boolean localTo(Customer other){
+ return areacode == other.areacode;
+ }
+
+ public Call call(Customer receiver) {
+ Call call = new Call(this, receiver);
+ addCall(call);
+ return call;
+ }
+
+ public void pickup(Call call) {
+ call.pickup();
+ addCall(call);
+ }
+
+ public void hangup(Call call) {
+ call.hangup(this);
+ removeCall(call);
+ }
+
+ public void merge(Call call1, Call call2){
+ call1.merge(call2);
+ removeCall(call2);
+ }
+ }
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Class <classname>Call</classname></title>
+
+ <para>
+ Calls are created with a caller and receiver who are customers. If the
+ caller and receiver have the same area code then the call can be
+ established with a <classname>Local</classname> connection (see below),
+ otherwise a <classname>LongDistance</classname> connection is required.
+ A call comprises a number of connections between customers. Initially
+ there is only the connection between the caller and receiver but
+ additional connections can be added if calls are merged to form
+ conference calls.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>The Class <classname>Connection</classname></title>
+
+ <para>The class <classname>Connection</classname> models the physical
+ details of establishing a connection between customers. It does this
+ with a simple state machine (connections are initially
+ <literal>PENDING</literal>, then <literal>COMPLETED</literal> and
+ finally <literal>DROPPED</literal>). Messages are printed to the
+ console so that the state of connections can be observed. Connection is
+ an abstract class with two concrete subclasses:
+ <classname>Local</classname> and <classname>LongDistance</classname>.
+ </para>
+
+<programlisting><![CDATA[
+ abstract class Connection {
+
+ public static final int PENDING = 0;
+ public static final int COMPLETE = 1;
+ public static final int DROPPED = 2;
+
+ Customer caller, receiver;
+ private int state = PENDING;
+
+ Connection(Customer a, Customer b) {
+ this.caller = a;
+ this.receiver = b;
+ }
+
+ public int getState(){
+ return state;
+ }
+
+ public Customer getCaller() { return caller; }
+
+ public Customer getReceiver() { return receiver; }
+
+ void complete() {
+ state = COMPLETE;
+ System.out.println("connection completed");
+ }
+
+ void drop() {
+ state = DROPPED;
+ System.out.println("connection dropped");
+ }
+
+ public boolean connects(Customer c){
+ return (caller == c || receiver == c);
+ }
+
+ }
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Class Local</title>
+
+<programlisting><![CDATA[
+ class Local extends Connection {
+ Local(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new local connection from " +
+ a + " to " + b + "]");
+ }
+ }
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Class LongDistance</title>
+
+<programlisting><![CDATA[
+ class LongDistance extends Connection {
+ LongDistance(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new long distance connection from " +
+ a + " to " + b + "]");
+ }
+ }
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Compiling and Running the Basic Simulation</title>
+
+ <para>
+ The source files for the basic system are listed in the file
+ <filename>basic.lst</filename>. To build and run the basic system, in a
+ shell window, type these commands:
+ </para>
+
+<programlisting><![CDATA[
+ajc -argfile telecom/basic.lst
+java telecom.BasicSimulation
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Timing</title>
+ <para>
+ The <classname>Timing</classname> aspect keeps track of total
+ connection time for each <classname>Customer</classname> by starting
+ and stopping a timer associated with each connection. It uses some
+ helper classes:
+ </para>
+
+ <sect4>
+ <title>The Class <classname>Timer</classname></title>
+
+ <para>
+ A <classname>Timer</classname> object simply records the current time
+ when it is started and stopped, and returns their difference when
+ asked for the elapsed time. The aspect
+ <classname>TimerLog</classname> (below) can be used to cause the
+ start and stop times to be printed to standard output.
+ </para>
+
+<programlisting><![CDATA[
+ class Timer {
+ long startTime, stopTime;
+
+ public void start() {
+ startTime = System.currentTimeMillis();
+ stopTime = startTime;
+ }
+
+ public void stop() {
+ stopTime = System.currentTimeMillis();
+ }
+
+ public long getTime() {
+ return stopTime - startTime;
+ }
+ }
+]]></programlisting>
+
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>The Aspect <classname>TimerLog</classname></title>
+
+ <para>
+ The aspect <classname>TimerLog</classname> can be included in a
+ build to get the timer to announce when it is started and stopped.
+ </para>
+
+<programlisting><![CDATA[
+public aspect TimerLog {
+
+ after(Timer t): target(t) && call(* Timer.start()) {
+ System.err.println("Timer started: " + t.startTime);
+ }
+
+ after(Timer t): target(t) && call(* Timer.stop()) {
+ System.err.println("Timer stopped: " + t.stopTime);
+ }
+}
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>The Aspect <classname>Timing</classname></title>
+
+ <para>
+ The aspect <classname>Timing</classname> introduces attribute
+ <literal>totalConnectTime</literal> into the class
+ <classname>Customer</classname> to store the accumulated connection
+ time per <classname>Customer</classname>. It introduces attribute
+ timer into <classname>Connection</classname> to associate a timer
+ with each <classname>Connection</classname>. Two pieces of after
+ advice ensure that the timer is started when a connection is
+ completed and and stopped when it is dropped. The pointcut
+ <literal>endTiming</literal> is defined so that it can be used by the
+ <classname>Billing</classname> aspect.
+ </para>
+
+<programlisting><![CDATA[
+public aspect Timing {
+
+ public long Customer.totalConnectTime = 0;
+
+ public long getTotalConnectTime(Customer cust) {
+ return cust.totalConnectTime;
+ }
+ private Timer Connection.timer = new Timer();
+ public Timer getTimer(Connection conn) { return conn.timer; }
+
+ after (Connection c): target(c) && call(void Connection.complete()) {
+ getTimer(c).start();
+ }
+
+ pointcut endTiming(Connection c): target(c) &&
+ call(void Connection.drop());
+
+ after(Connection c): endTiming(c) {
+ getTimer(c).stop();
+ c.getCaller().totalConnectTime += getTimer(c).getTime();
+ c.getReceiver().totalConnectTime += getTimer(c).getTime();
+ }
+}]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Billing</title>
+
+ <para>
+ The Billing system adds billing functionality to the telecom
+ application on top of timing.
+ </para>
+
+ <sect4>
+ <title>The Aspect <classname>Billing</classname></title>
+
+ <para>
+ The aspect <classname>Billing</classname> introduces attribute
+ <literal>payer</literal> into <classname>Connection</classname>
+ to indicate who initiated the call and therefore who is
+ responsible to pay for it. It also introduces method
+ <literal>callRate</literal> into <classname>Connection</classname>
+ so that local and long distance calls can be charged
+ differently. The call charge must be calculated after the timer is
+ stopped; the after advice on pointcut
+ <literal>Timing.endTiming</literal> does this and
+ <classname>Billing</classname> dominates Timing to make
+ sure that this advice runs after <classname>Timing's</classname>
+ advice on the same join point. It introduces attribute
+ <literal>totalCharge</literal> and its associated methods into
+ <classname>Customer</classname> (to manage the
+ customer's bill information.
+ </para>
+
+<programlisting><![CDATA[
+public aspect Billing dominates Timing {
+ // domination required to get advice on endtiming in the right order
+
+ public static final long LOCAL_RATE = 3;
+ public static final long LONG_DISTANCE_RATE = 10;
+
+
+ public Customer Connection.payer;
+ public Customer getPayer(Connection conn) { return conn.payer; }
+
+ after(Customer cust) returning (Connection conn):
+ args(cust, ..) && call(Connection+.new(..)) {
+ conn.payer = cust;
+ }
+
+ public abstract long Connection.callRate();
+
+
+ public long LongDistance.callRate() { return LONG_DISTANCE_RATE; }
+ public long Local.callRate() { return LOCAL_RATE; }
+
+
+ after(Connection conn): Timing.endTiming(conn) {
+ long time = Timing.aspectOf().getTimer(conn).getTime();
+ long rate = conn.callRate();
+ long cost = rate * time;
+ getPayer(conn).addCharge(cost);
+ }
+
+
+ public long Customer.totalCharge = 0;
+ public long getTotalCharge(Customer cust) { return cust.totalCharge; }
+
+ public void Customer.addCharge(long charge){
+ totalCharge += charge;
+ }
+}
+]]></programlisting>
+
+ </sect4>
+ </sect3>
+
+ <sect3>
+ <title>Accessing the Introduced State</title>
+
+ <para>
+ Both the aspects <classname>Timing</classname> and
+ <classname>Billing</classname> contain the definition of operations
+ that the rest of the system may want to access. For example, when
+ running the simulation with one or both aspects, we want to find out
+ how much time each customer spent on the telephone and how big their
+ bill is. That information is also stored in the classes, but they are
+ accessed through static methods of the aspects, since the state they
+ refer to is private to the aspect.
+ </para>
+
+ <para>
+ Take a look at the file <filename>TimingSimulation.java</filename>. The
+ most important method of this class is the method
+ <filename>report(Customer c)</filename>, which is used in the method
+ run of the superclass <classname>AbstractSimulation</classname>. This
+ method is intended to print out the status of the customer, with
+ respect to the <classname>Timing</classname> feature.
+ </para>
+
+<programlisting><![CDATA[
+ protected void report(Customer c){
+ Timing t = Timing.aspectOf();
+ System.out.println(c + " spent " + t.getTotalConnectTime(c));
+ }
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Compiling and Running</title>
+
+ <para>
+ The files timing.lst and billing.lst contain file lists for the timing
+ and billing configurations. To build and run the application with only
+ the timing feature, go to the directory examples and type:
+ </para>
+
+<programlisting><![CDATA[
+ ajc -argfile telecom/timing.lst
+ java telecom.TimingSimulation
+]]></programlisting>
+
+ <para>
+ To build and run the application with the timing and billing features,
+ go to the directory examples and type:
+ </para>
+
+<programlisting><![CDATA[
+ ajc -argfile telecom/billing.lst
+ java telecom.BillingSimulation
+]]></programlisting>
+
+ </sect3>
+
+ <sect3>
+ <title>Discussion</title>
+
+ <para>
+ There are some explicit dependencies between the aspects Billing and
+ Timing:
+ <itemizedlist>
+ <listitem>
+ <para>
+ Billing is declared to dominate Timing so that Billing's after
+ advice runs after that of Timing when they are on the same join
+ point.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Billing uses the pointcut Timing.endTiming.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Billing needs access to the timer associated with a connection.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </sect3>
+ </sect2>
+ </sect1>
+
+<!-- ============================================================ -->
+<!-- ============================================================ -->
+
+ <sect1>
+ <title>Reusable Aspects</title>
+
+ <sect2>
+ <title>Tracing Aspects Revisited</title>
+
+ <para>(The code for this example is in
+ <filename><replaceable>InstallDir</replaceable>/examples/tracing</filename>.)
+ </para>
+
+ <sect3>
+ <title>Tracing&mdash;Version 3</title>
+
+ <para>
+ One advantage of not exposing the methods traceEntry and traceExit as
+ public operations is that we can easily change their interface without
+ any dramatic consequences in the rest of the code.
+ </para>
+
+ <para>
+ Consider, again, the program without AspectJ. Suppose, for example,
+ that at some point later the requirements for tracing change, stating
+ that the trace messages should always include the string representation
+ of the object whose methods are being traced. This can be achieved in
+ at least two ways. One way is keep the interface of the methods
+ <literal>traceEntry</literal> and <literal>traceExit</literal> as it
+ was before,
+ </para>
+
+<programlisting><![CDATA[
+ public static void traceEntry(String str);
+ public static void traceExit(String str);
+]]></programlisting>
+
+ <para>
+ In this case, the caller is responsible for ensuring that the string
+ representation of the object is part of the string given as argument.
+ So, calls must look like:
+ </para>
+
+<programlisting><![CDATA[
+ Trace.traceEntry("Square.distance in " + toString());
+]]></programlisting>
+
+ <para>
+ Another way is to enforce the requirement with a second argument in the
+ trace operations, e.g.
+ </para>
+
+<programlisting><![CDATA[
+ public static void traceEntry(String str, Object obj);
+ public static void traceExit(String str, Object obj);
+]]></programlisting>
+
+ <para>
+ In this case, the caller is still responsible for sending the right
+ object, but at least there is some guarantees that some object will be
+ passed. The calls will look like:
+ </para>
+
+<programlisting><![CDATA[
+ Trace.traceEntry("Square.distance", this);
+]]></programlisting>
+
+ <para>
+ In either case, this change to the requirements of tracing will have
+ dramatic consequences in the rest of the code -- every call to the
+ trace operations traceEntry and traceExit must be changed!
+ </para>
+
+ <para>
+ Here's another advantage of doing tracing with an aspect. We've already
+ seen that in version 2 <literal>traceEntry</literal> and
+ <literal>traceExit</literal> are not publicly exposed. So changing
+ their interfaces, or the way they are used, has only a small effect
+ inside the <classname>Trace</classname> class. Here's a partial view at
+ the implementation of <classname>Trace</classname>, version 3. The
+ differences with respect to version 2 are stressed in the
+ comments:
+ </para>
+
+<programlisting><![CDATA[
+abstract aspect Trace {
+
+ public static int TRACELEVEL = 0;
+ protected static PrintStream stream = null;
+ protected static int callDepth = 0;
+
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+
+ protected static void traceEntry(String str, Object o) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str + ": " + o.toString());
+ }
+
+ protected static void traceExit(String str, Object o) {
+ if (TRACELEVEL == 0) return;
+ printExiting(str + ": " + o.toString());
+ if (TRACELEVEL == 2) callDepth--;
+ }
+
+ private static void printEntering(String str) {
+ printIndent();
+ stream.println("Entering " + str);
+ }
+
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("Exiting " + str);
+ }
+
+
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+
+
+ abstract pointcut myClass(Object obj);
+
+ pointcut myConstructor(Object obj): myClass(obj) && execution(new(..));
+ pointcut myMethod(Object obj): myClass(obj) &&
+ execution(* *(..)) && !execution(String toString());
+
+ before(Object obj): myConstructor(obj) {
+ traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+ after(Object obj): myConstructor(obj) {
+ traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+
+ before(Object obj): myMethod(obj) {
+ traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+ after(Object obj): myMethod(obj) {
+ traceExit("" + thisJoinPointStaticPart.getSignature(), obj);
+ }
+}
+]]></programlisting>
+
+ <para>
+ As you can see, we decided to apply the first design by preserving the
+ interface of the methods <literal>traceEntry</literal> and
+ <literal>traceExit</literal>. But it doesn't matter&mdash;we could as
+ easily have applied the second design (the code in the directory
+ <filename>examples/tracing/version3</filename> has the second design).
+ The point is that the effects of this change in the tracing
+ requirements are limited to the <classname>Trace</classname> aspect
+ class.
+ </para>
+
+ <para>
+ One implementation change worth noticing is the specification of the
+ pointcuts. They now expose the object. To maintain full consistency
+ with the behavior of version 2, we should have included tracing for
+ static methods, by defining another pointcut for static methods and
+ advising it. We leave that as an exercise.
+ </para>
+
+ <para>
+ Moreover, we had to exclude the execution join point of the method
+ <filename>toString</filename> from the <literal>methods</literal>
+ pointcut. The problem here is that <literal>toString</literal> is being
+ called from inside the advice. Therefore if we trace it, we will end
+ up in an infinite recursion of calls. This is a subtle point, and one
+ that you must be aware when writing advice. If the advice calls back to
+ the objects, there is always the possibility of recursion. Keep that in
+ mind!
+ </para>
+
+ <para>
+ In fact, esimply excluding the execution join point may not be enough,
+ if there are calls to other traced methods within it -- in which case,
+ the restriction should be
+ </para>
+
+<programlisting><![CDATA[
+&& !cflow(execution(String toString()))
+]]></programlisting>
+
+ <para>
+ excluding both the execution of toString methods and all join points
+ under that execution.
+ </para>
+
+ <para>
+ In summary, to implement the change in the tracing requirements we had
+ to make a couple of changes in the implementation of the
+ <classname>Trace</classname> aspect class, including changing the
+ specification of the pointcuts. That's only natural. But the
+ implementation changes were limited to this aspect. Without aspects, we
+ would have to change the implementation of every application class.
+ </para>
+
+ <para>
+ Finally, to run this version of tracing, go to the directory
+ <filename>examples</filename> and type:
+ </para>
+
+<programlisting><![CDATA[
+ajc -argfile tracing/tracev3.lst
+]]></programlisting>
+
+ <para>
+ The file tracev3.lst lists the application classes as well as this
+ version of the files <filename>Trace.java</filename> and
+ <filename>TraceMyClasses.java</filename>. To run the program, type
+ </para>
+
+<programlisting><![CDATA[
+java tracing.version3.TraceMyClasses
+]]></programlisting>
+
+ <para>The output should be:</para>
+
+<programlisting><![CDATA[
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Circle(double, double, double)
+ <-- tracing.Circle(double, double, double)
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Circle(double, double, double)
+ <-- tracing.Circle(double, double, double)
+ --> tracing.Circle(double)
+ <-- tracing.Circle(double)
+ --> tracing.TwoDShape(double, double)
+ <-- tracing.TwoDShape(double, double)
+ --> tracing.Square(double, double, double)
+ <-- tracing.Square(double, double, double)
+ --> tracing.Square(double, double)
+ <-- tracing.Square(double, double)
+ --> double tracing.Circle.perimeter()
+ <-- double tracing.Circle.perimeter()
+c1.perimeter() = 12.566370614359172
+ --> double tracing.Circle.area()
+ <-- double tracing.Circle.area()
+c1.area() = 12.566370614359172
+ --> double tracing.Square.perimeter()
+ <-- double tracing.Square.perimeter()
+s1.perimeter() = 4.0
+ --> double tracing.Square.area()
+ <-- double tracing.Square.area()
+s1.area() = 1.0
+ --> double tracing.TwoDShape.distance(TwoDShape)
+ --> double tracing.TwoDShape.getX()
+ <-- double tracing.TwoDShape.getX()
+ --> double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.distance(TwoDShape)
+c2.distance(c1) = 4.242640687119285
+ --> double tracing.TwoDShape.distance(TwoDShape)
+ --> double tracing.TwoDShape.getX()
+ <-- double tracing.TwoDShape.getX()
+ --> double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.getY()
+ <-- double tracing.TwoDShape.distance(TwoDShape)
+s1.distance(c1) = 2.23606797749979
+ --> String tracing.Square.toString()
+ --> String tracing.TwoDShape.toString()
+ <-- String tracing.TwoDShape.toString()
+ <-- String tracing.Square.toString()
+s1.toString(): Square side = 1.0 @ (1.0, 2.0)
+]]></programlisting>
+
+ </sect3>
+ </sect2>
+ </sect1>
+</chapter>
+
+<!--
+Local variables:
+compile-command: "java sax.SAXCount -v progguide.xml && java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl"
+fill-column: 79
+sgml-local-ecat-files: "progguide.ced"
+sgml-parent-document:("progguide.xml" "book" "chapter")
+End:
+-->
diff --git a/docs/progGuideDB/figureUML.gif b/docs/progGuideDB/figureUML.gif
new file mode 100644
index 000000000..c4bf8db9a
--- /dev/null
+++ b/docs/progGuideDB/figureUML.gif
Binary files differ
diff --git a/docs/progGuideDB/gettingstarted.xml b/docs/progGuideDB/gettingstarted.xml
new file mode 100644
index 000000000..7cd6becbd
--- /dev/null
+++ b/docs/progGuideDB/gettingstarted.xml
@@ -0,0 +1,1090 @@
+<chapter id="gettingstarted" xreflabel="Getting Started with AspectJ">
+
+ <title>Getting Started with AspectJ</title>
+
+ <sect1>
+ <title>Introduction</title>
+
+ <para>Many software developers are attracted to the idea of aspect-oriented
+ programming
+ <indexterm>
+ <primary>aspect-oriented programming</primary>
+ </indexterm>
+ (AOP)
+ <indexterm>
+ <primary>AOP</primary>
+ <see> aspect-oriented programming</see>
+ </indexterm>
+ but unsure about how to begin using the technology. They
+ recognize the concept of crosscutting concerns, and know that they have
+ had problems with the implementation of such concerns in the past. But
+ there are many questions about how to adopt AOP into the development
+ process. Common questions include:
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>Can I use aspects in my existing code?</para>
+ </listitem>
+ <listitem>
+ <para>What kinds of benefits can I expect to get from using aspects?
+ </para>
+ </listitem>
+ <listitem>
+ <para>How do I find aspects in my programs?</para>
+ </listitem>
+ <listitem>
+ <para>How steep is the learning curve for AOP?</para>
+ </listitem>
+ <listitem>
+ <para>What are the risks of using this new technology?</para>
+ </listitem>
+ </itemizedlist></para>
+
+ <para>This chapter addresses these questions in the context of AspectJ a
+ general-purpose aspect-oriented extension to Java. A series of abridged
+ examples illustrate the kinds of aspects programmers may want to
+ implement using AspectJ and the benefits associated with doing so.
+ Readers who would like to understand the examples in more detail, or who
+ want to learn how to program examples like these, can find the complete
+ examples and supporting material on the AspectJ web site(<ulink
+ url="http://aspectj.org/documentation/papersAndSlides/figures-cacm2001.zip"></ulink>).</para>
+
+ <para>A significant risk in adopting any new technology is going too
+ far too fast. Concern about this risk causes many organizations to
+ be conservative about adopting new technology. To address this
+ issue, the examples in this chapter are grouped into three broad
+ categories, with aspects that are easier to adopt into existing
+ development projects coming earlier in this chapter. The next
+ section, <xref linkend="aspectjsemantics"/>, we present the core
+ of AspectJ's semantics, and in <xref linkend="developmentaspects"/>,
+ we present aspects that facilitate tasks such as debugging,
+ testing and performance tuning of applications. And, in the section
+ following, <xref linkend="productionaspects"/>, we present aspects
+ that implement crosscutting functionality common in Java
+ applications. We will defer discussing a third category of aspects,
+ reusable aspects until <xref linkend="aspectjlanguage"/>. </para>
+
+ <para>These categories are informal, and this ordering is not the only way
+ to adopt AspectJ. Some developers may want to use a production aspect
+ right away. But our experience with current AspectJ users suggests that
+ this is one ordering that allows developers to get experience with (and
+ benefit from) AOP technology quickly, while also minimizing risk.</para>
+
+ </sect1>
+
+ <sect1 id="aspectjsemantics" xreflabel="AspectJ Semantics">
+ <title>AspectJ Semantics</title>
+
+ <indexterm>
+ <primary>AspectJ</primary>
+ <secondary>semantics</secondary>
+ <tertiary>overview</tertiary>
+ </indexterm>
+
+ <para>This section presents a brief introduction to the features of AspectJ
+ used later in this chapter. These features are at the core of the
+ language, but this is by no means a complete overview of AspectJ.</para>
+
+ <para>The semantics are presented using a simple figure editor system. A
+ <classname>Figure</classname> consists of a number of
+ <classname>FigureElements</classname>, which can be either
+ <classname>Point</classname>s or <classname>Line</classname>s. The
+ <classname>Figure</classname> class provides factory services. There is
+ also a <classname>Display</classname>. Most example programs later in
+ this chapter are based on this system as well.</para>
+
+ <para>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="figureUML.gif"/>
+ </imageobject>
+ <caption><para>UML for the <literal>FigureEditor</literal>
+ example</para></caption>
+ </mediaobject>
+ </para>
+
+ <para>The motivation for AspectJ (and likewise for aspect-oriented
+ programming) is the realization that there are issues or concerns
+ that are not well captured by traditional programming
+ methodologies. Consider the problem of enforcing a security policy
+ in some application. By its nature, security cuts across many of
+ the natural units of modularity of the application. Moreover, the
+ security policy must be uniformly applied to any additions as the
+ application evolves. And the security policy that is being applied
+ might itself evolve. Capturing concerns like a security policy in
+ a disciplined way is difficult and error-prone in a traditional
+ programming language.</para>
+
+ <para>Concerns like security cut across the natural units of
+ modularity. For object-oriented programming languages, the natural
+ unit of modularity is the class. But in object-oriented
+ programming languages, crosscutting concerns are not easily turned
+ into classes precisely because they cut across classes, and so
+ these aren't reusable, they can't be refined or inherited,
+ they are spread through out the program in an undisciplined way,
+ in short, they are difficult to work with.</para>
+
+ <para>Aspect-oriented programming is a way of modularizing
+ crosscutting concerns much like object-oriented programming is a
+ way of modularizing common concerns. AspectJ is an implementation
+ of aspect-oriented programming for Java.</para>
+
+ <para>AspectJ adds to Java just one new concept, a join point, and
+ a few new constructs: pointcuts, advice, introduction and aspects.
+ Pointcuts and advice dynamically affect program flow, and
+ introduction statically affects a program's class
+ heirarchy.</para>
+
+ <para>A <emphasis>join point</emphasis>
+ <indexterm><primary>join point</primary></indexterm>
+ is a well-defined point in the program flow.
+ <emphasis>Pointcuts</emphasis>
+ <indexterm><primary>pointcut</primary></indexterm>
+ select certain join points and values at those points.
+ <emphasis>Advice</emphasis>
+ <indexterm> <primary>advice</primary></indexterm>
+ defines code that is executed when a pointcut is reached. These
+ are, then, the dynamic parts of AspectJ.</para>
+
+ <para>AspectJ also has a way of affecting a program statically.
+ <emphasis>Introduction</emphasis>
+ <indexterm><primary>introduction</primary></indexterm>
+ is how AspectJ modifies a program's static structure, namely, the
+ members of its classes and the relationship between
+ classes.</para>
+
+ <para>The last new construct in AspectJ is the
+ <emphasis>aspect</emphasis>.
+ <indexterm><primary>aspect</primary></indexterm>
+ Aspects, are AspectJ's unit of modularity for crosscutting
+ concerns They are defined in terms of pointcuts, advice and
+ introduction.</para>
+
+ <para>In the sections immediately following, we are first going to look at
+ join points and how they compose into pointcuts. Then we will look
+ at advice, the code which is run when a pointcut is reached. We
+ will see how to combine pointcuts and advice into aspects, AspectJ's
+ reusable, inheritable unit of modularity. Lastly, we will look at
+ how to modify a program's class structure with introduction. </para>
+
+ <sect2>
+ <title>The Dynamic Join Point Model</title>
+ <indexterm>
+ <primary>join point</primary>
+ <secondary>model</secondary>
+ </indexterm>
+
+ <para>A critical element in the design of any aspect-oriented
+ language is the join point model. The join point model provides
+ the common frame of reference that makes it possible to define
+ the dynamic structure of crosscutting concerns.</para>
+
+ <para>This chapter describes AspectJ's dynamic join points, in
+ which join points are certain well-defined points in the
+ execution of the program. Later we will discuss introduction,
+ AspectJ's form for modifying a program statically. </para>
+
+ <para>AspectJ provides for many kinds of join points, but this
+ chapter discusses only one of them: method call join points. A
+ method call join point encompasses the actions of an object
+ receiving a method call. It includes all the actions that
+ comprise a method call, starting after all arguments are
+ evaluated up to and including normal or abrupt return.</para>
+
+ <para>Each method call itself is one join point. The dynamic
+ context of a method call may include many other join points: all
+ the join points that occur when executing the called method and
+ any methods that it calls.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Pointcut Designators</title>
+
+ <para>In AspectJ, <emphasis>pointcut designators</emphasis> (or
+ simply pointcuts) identify certain join points in the program
+ flow. For example, the pointcut</para>
+
+ <programlisting format="linespecific">
+call(void Point.setX(int))</programlisting>
+
+ <para>identifies any call to the method <function>setX</function>
+ defined on <classname>Point</classname> objects. Pointcuts can be
+ composed using a filter composition semantics, so for example:</para>
+
+ <programlisting format="linespecific">
+call(void Point.setX(int)) ||
+call(void Point.setY(int))</programlisting>
+
+ <para>identifies any call to either the <function>setX</function> or
+ <function>setY</function> methods defined by
+ <classname>Point</classname>.</para>
+
+ <para>Programmers can define their own pointcuts, and pointcuts
+ can identify join points from many different classes &mdash; in
+ other words, they can crosscut classes. So, for example, the
+ following declares a new, named pointcut:</para>
+
+<programlisting format="linespecific">
+pointcut move(): call(void FigureElement.setXY(int,int)) ||
+ call(void Point.setX(int)) ||
+ call(void Point.setY(int)) ||
+ call(void Line.setP1(Point)) ||
+ call(void Line.setP2(Point));</programlisting>
+
+ <para>The effect of this declaration is that <function>move</function> is
+ now a pointcut that identifies any call to methods that move figure
+ elements. </para>
+
+ <sect3>
+ <title>Property-Based Primitive Pointcuts</title>
+ <indexterm>
+ <primary>pointcut</primary>
+ <secondary>primitive</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>pointcut</primary>
+ <secondary>name-based</secondary>
+ </indexterm>
+ <indexterm>
+ <primary>pointcut</primary>
+ <secondary>property-based</secondary>
+ </indexterm>
+
+ <para>The previous pointcuts are all based on explicit enumeration
+ of a set of method signatures. We call this
+ <emphasis>name-based</emphasis> crosscutting. AspectJ also
+ provides mechanisms that enable specifying a pointcut in terms
+ of properties of methods other than their exact name. We call
+ this <emphasis>property-based</emphasis> crosscutting. The
+ simplest of these involve using wildcards in certain fields of
+ the method signature. For example:</para>
+
+<programlisting format="linespecific">
+call(void Figure.make*(..))</programlisting>
+
+ <para>identifies calls to any method defined on
+ <classname>Figure</classname>, for which the name begins with
+ "<function>make</function>", specifically the factory methods
+ <function>makePoint</function> and <function>makeLine</function>;
+ and</para>
+
+ <programlisting format="linespecific">
+call(public * Figure.* (..))</programlisting>
+
+ <para>identifies calls to any public method defined on
+ <classname>Figure</classname>.</para>
+
+ <para>One very powerful primitive pointcut,
+ <function>cflow</function>, identifies join points based on whether
+ they occur in the dynamic context of another pointcut. So</para>
+
+ <programlisting format="linespecific">
+cflow(move())</programlisting>
+
+ <para>identifies all join points that occur between receiving method
+ calls for the methods in <function>move</function> and returning from
+ those calls (either normally or by throwing an exception.) </para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Advice</title>
+ <indexterm>
+ <primary>advice</primary>
+ </indexterm>
+
+ <para>Pointcuts are used in the definition of advice. AspectJ has
+ several different kinds of advice that define additional code that
+ should run at join points. <emphasis>Before advice</emphasis>
+ <indexterm>
+ <primary>advice</primary>
+ <secondary>before</secondary>
+ </indexterm>
+ runs when a join point is reached and
+ before the computation proceeds, i.e. it runs when computation
+ reaches the method call and before the actual method starts running.
+ <emphasis>After advice</emphasis>
+ <indexterm>
+ <primary>advice</primary>
+ <secondary>after</secondary>
+ </indexterm>
+ runs after the computation 'under the join point' finishes, i.e. after
+ the method body has run, and just before control is returned to the
+ caller. <emphasis>Around advice</emphasis>
+ <indexterm>
+ <primary>advice</primary>
+ <secondary>around</secondary>
+ </indexterm>
+ runs when the join point is reached, and has explicit control over
+ whether the computation under the join point is allowed to run at
+ all. (Around advice and some variants of after advice are not
+ discussed in this chapter.)</para>
+
+<programlisting><![CDATA[
+after(): move() {
+ System.out.println("A figure element moved.");
+}
+]]></programlisting>
+
+ <sect3>
+ <title>Exposing Context in Pointcuts</title>
+
+ <para>Pointcuts can also expose part of the execution context at
+ their join points. Values exposed by a pointcut can be used in
+ the body of advice declarations. In the following code, the
+ pointcut exposes three values from calls to
+ <function>setXY</function>: the
+ <classname>FigureElement</classname> receiving the call, the
+ new value for <literal>x</literal> and the new value for
+ <literal>y</literal>. The advice then prints the figure
+ element that was moved and its new <literal>x</literal> and
+ <literal>y</literal> coordinates after each
+ <classname>setXY</classname> method call.</para>
+
+<programlisting><![CDATA[
+pointcut setXY(FigureElement fe, int x, int y):
+ call(void FigureElement.setXY(int, int))
+ && target(fe)
+ && args(x, y);
+
+after(FigureElement fe, int x, int y): setXY(fe, x, y) {
+ System.out.println(fe + " moved to (" + x + ", " + y + ").");
+}
+]]></programlisting>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Introduction</title>
+ <indexterm><primary>aspect</primary></indexterm>
+
+ <para>Introduction is AspectJ's form for modifying classes and their
+ hierarchy. Introduction adds new members to classes and alters the
+ inheritance relationship between classes. Unlike advice that operates
+ primarily dynamically, introduction operates statically, at compilation
+ time. Introduction changes the declaration of classes, and it is these
+ changed classes that are inherited, extended or instantiated by the
+ rest of the program.</para>
+
+ <para>Consider the problem of adding a new capability to some existing
+ classes that are already part of a class heirarchy, i.e. they already
+ extend a class. In Java, one creates an interface that captures
+ this new capability, and then adds to <emphasis>each affected
+ class</emphasis> a method that implements this interface.</para>
+
+ <para>AspectJ can do better. The new capability is a crosscutting concern
+ because it affects multiple classes. Using AspectJ's introduction form,
+ we can introduce into existing classes the methods or fields that are
+ necessary to implement the new capability.
+ </para>
+
+ <para>Suppose we want to have <classname>Screen</classname> objects
+ observe changes to <classname>Point</classname> objects, where
+ <classname>Point</classname> is an existing class. We can implement
+ this by introducing into the class <classname>Point</classname> an
+ instance field, <varname>observers</varname>, that keeps track of the
+ <classname>Screen</classname> objects that are observing
+ <classname>Point</classname>s. Observers are added or removed with the
+ static methods <function>addObserver</function> and
+ <function>removeObserver</function>. The pointcut
+ <function>changes</function> defines what we want to observe, and the
+ after advice defines what we want to do when we observe a change. Note
+ that neither <classname>Screen</classname>'s nor
+ <classname>Point</classname>'s code has to be modified, and that all
+ the changes needed to support this new capability are local to this
+ aspect.</para>
+
+ <programlisting><![CDATA[
+aspect PointObserving {
+
+ private Vector Point.observers = new Vector();
+
+ public static void addObserver(Point p, Screen s) {
+ p.observers.add(s);
+ }
+
+ public static void removeObserver(Point p, Screen s) {
+ p.observers.remove(s);
+ }
+
+ pointcut changes(Point p): target(p) && call(void Point.set*(int));
+
+ after(Point p): changes(p) {
+ Iterator iter = p.observers.iterator();
+ while ( iter.hasNext() ) {
+ updateObserver(p, (Screen)iter.next());
+ }
+ }
+
+ static void updateObserver(Point p, Screen s) {
+ s.display(p);
+ }
+}]]></programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Aspect Declarations</title>
+
+ <para>An <emphasis>aspect</emphasis>
+ <indexterm><primary>aspect</primary></indexterm> is a modular unit of
+ crosscutting implementation. It is defined very much like a class,
+ and can have methods, fields, and initializers. The crosscutting
+ implementation is provided in terms of pointcuts, advice and
+ introductions. Only aspects may include advice, so while AspectJ
+ may define crosscutting effects, the declaration of those effects is
+ localized.</para>
+
+ <para>The next three sections present the use of aspects in
+ increasingly sophisticated ways. Development aspects are easily removed
+ from production builds. Production aspects are intended to be used in
+ both development and in production, but tend to affect only a few
+ classes. Finally, reusable aspects require the most experience to get
+ right.</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="developmentaspects" xreflabel="Development Aspects">
+ <title>Development Aspects</title>
+ <indexterm>
+ <primary>aspect</primary>
+ <secondary>development</secondary>
+ </indexterm>
+
+ <para>This section presents examples of aspects that can be used during
+ development of Java applications. These aspects facilitate debugging,
+ testing and performance tuning work. The aspects define behavior that
+ ranges from simple tracing, to profiling, to testing of internal
+ consistency within the application. Using AspectJ makes it possible to
+ cleanly modularize this kind of functionality, thereby making it possible
+ to easily enable and disable the functionality when desired. </para>
+
+ <sect2>
+ <title>Tracing, Logging, and Profiling</title>
+ <indexterm>
+ <primary>tracing</primary>
+ </indexterm>
+ <indexterm>
+ <primary>logging</primary>
+ </indexterm>
+ <indexterm>
+ <primary>profiling</primary>
+ </indexterm>
+
+ <para>This first example shows how to increase the visibility of the
+ internal workings of a program. It is a simple tracing aspect that
+ prints a message at specified method calls. In our figure editor
+ example, one such aspect might simply trace whenever points are
+ drawn.</para>
+
+<programlisting><![CDATA[
+aspect SimpleTracing {
+ pointcut tracedCall():
+ call(void FigureElement.draw(GraphicsContext));
+
+ before(): tracedCall() {
+ System.out.println("Entering: " + thisJoinPoint);
+ }
+}
+]]></programlisting>
+
+ <para>This code makes use of the <literal>thisJoinPoint</literal> special
+ variable. Within all advice bodies this variable is bound to an object
+ that describes the current join point. The effect of this code
+ is to print a line like the following every time a figure element
+ receives a <function>draw</function> method call:</para>
+
+<programlisting><![CDATA[
+Entering: call(void FigureElement.draw(GraphicsContext))
+]]></programlisting>
+
+ <para>To understand the benefit of coding this with AspectJ consider
+ changing the set of method calls that are traced. With AspectJ, this
+ just requires editing the definition of the
+ <function>tracedCalls</function> pointcut and recompiling. The
+ individual methods that are traced do not need to be edited.</para>
+
+ <para>When debugging, programmers often invest considerable effort in
+ figuring out a good set of trace points to use when looking for a
+ particular kind of problem. When debugging is complete or appears to
+ be complete it is frustrating to have to lose that investment by
+ deleting trace statements from the code. The alternative of just
+ commenting them out makes the code look bad, and can cause trace
+ statements for one kind of debugging to get confused with trace
+ statements for another kind of debugging.</para>
+
+ <para>With AspectJ it is easy to both preserve the work of designing a
+ good set of trace points and disable the tracing when it isn t being
+ used. This is done by writing an aspect specifically for that tracing
+ mode, and removing that aspect from the compilation when it is not
+ needed.</para>
+
+ <para>This ability to concisely implement and reuse debugging
+ configurations that have proven useful in the past is a direct result
+ of AspectJ modularizing a crosscutting design element the set of
+ methods that are appropriate to trace when looking for a given kind of
+ information.</para>
+
+ <sect3>
+ <title>Profiling and Logging</title>
+ <indexterm><primary>logging</primary></indexterm>
+ <indexterm><primary>profiling</primary></indexterm>
+
+ <para> Our second example shows you how to do some very specific
+ profiling. Although many sophisticated profiling tools are available,
+ and these can gather a variety of information and display the results
+ in useful ways, you may sometimes want to profile or log some very
+ specific behavior. In these cases, it is often possible to write a
+ simple aspect similar to the ones above to do the job.</para>
+
+ <para>For example, the following aspect<footnote>
+ <para>Since aspects are by default singleton aspects, i.e. there is
+ only one instance of the aspect, fields in a singleton aspect are
+ similar to static fields in class.</para></footnote> will count
+ the number of calls to the <function>rotate</function> method on a
+ <classname>Line</classname> and the number of calls to the
+ <function>set*</function> methods of a <classname>Point</classname>
+ that happen within the control flow of those calls to
+ <function>rotate</function>:</para>
+
+<programlisting><![CDATA[
+aspect SetsInRotateCounting {
+ int rotateCount = 0;
+ int setCount = 0;
+
+ before(): call(void Line.rotate(double)) {
+ rotateCount++;
+ }
+
+ before(): call(void Point.set*(int)) &&
+ cflow(call(void Line.rotate(double))) {
+ setCount++;
+ }
+}]]></programlisting>
+
+ <para>Aspects have an advantage over standard profiling or logging
+ tools because they can be programmed to ask very specific and complex
+ questions like, "How many times is the <function>rotate</function>
+ method defined on <classname>Line</classname> objects called, and how
+ many times are methods defined on <classname>Point</classname>
+ objects whose name begins with `<function>set</function>' called in
+ fulfilling those rotate calls"?</para>
+
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Pre- and Post-Conditions</title>
+
+ <indexterm><primary>pre-condition</primary></indexterm>
+ <indexterm><primary>post-condition</primary></indexterm>
+ <indexterm><primary>assertion</primary></indexterm>
+
+ <para>Many programmers use the "Design by Contract" style popularized by
+ Bertand Meyer in <citetitle>Object-Oriented Software Construction,
+ 2/e</citetitle>. In this style of programming, explicit
+ pre-conditions test that callers of a method call it properly and
+ explicit post-conditions test that methods properly do the work they
+ are supposed to.</para>
+
+ <para>
+ AspectJ makes it possible to implement pre- and post-condition testing
+ in modular form. For example, this code </para>
+
+
+ <programlisting><![CDATA[
+aspect PointBoundsChecking {
+
+ pointcut setX(int x):
+ (call(void FigureElement.setXY(int, int)) && args(x, *))
+ || (call(void Point.setX(int)) && args(x));
+
+ pointcut setY(int y):
+ (call(void FigureElement.setXY(int, int)) && args(*, y))
+ || (call(void Point.setY(int)) && args(y));
+
+ before(int x): setX(x) {
+ if ( x < MIN_X || x > MAX_X )
+ throw new IllegalArgumentException("x is out of bounds.");
+ }
+
+ before(int y): setY(y) {
+ if ( y < MIN_Y || y > MAX_Y )
+ throw new IllegalArgumentException("y is out of bounds.");
+ }
+}
+]]></programlisting>
+
+ <para>implements the bounds checking aspect of pre-condition testing for
+ operations that move points. Notice that the <function>setX</function>
+ pointcut refers to all the operations that can set a point's
+ <literal>x</literal> coordinate; this includes the
+ <function>setX</function> method, as well as half of the
+ <function>setXY</function> method. In this sense the
+ <function>setX</function> pointcut can be seen as involving very
+ fine-grained crosscutting&mdash;it names the the
+ <function>setX</function> method and half of the
+ <function>setXY</function> method.</para>
+
+ <para>Even though pre- and post-condition testing aspects can often be
+ used only during testing, in some cases developers may wish to include
+ them in the production build as well. Again, because AspectJ makes it
+ possible to modularize these crosscutting concerns cleanly, it gives
+ developers good control over this decision.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Contract Enforcement</title>
+ <indexterm><primary>contract enforcement</primary></indexterm>
+
+<!-- <remark>What is a compelling example of runtime contract enforcement that has -->
+<!-- croscutting concerns so that Java 1.4-based assertions won't be -->
+<!-- sufficient? -->
+<!-- </remark> -->
+ <para>
+ The property-based crosscutting mechanisms can be very useful in
+ defining more sophisticated contract enforcement. One very powerful
+ use of these mechanisms is to identify method calls that, in a correct
+ program, should not exist. For example, the following aspect enforces
+ the constraint that only the well-known factory methods can add an
+ element to the registry of figure elements. Enforcing this constraint
+ ensures that no figure element is added to the registry more than
+ once.</para>
+
+<programlisting><![CDATA[
+static aspect RegistrationProtection {
+
+ pointcut register(): call(void Registry.register(FigureElement));
+
+ pointcut canRegister(): withincode(static * FigureElement.make*(..));
+
+ before(): register() && !canRegister() {
+ throw new IllegalAccessException("Illegal call " + thisJoinPoint);
+ }
+}
+]]></programlisting>
+
+ <para>This aspect uses the withincode primitive pointcut to denote all
+ join points that occur within the body of the factory methods on
+ <classname>FigureElement</classname> (the methods with names that begin
+ with "<literal>make</literal>"). This is a property-based pointcut
+ because it identifies join points based not on their signature, but
+ rather on the property that they occur specifically within the code of
+ another method. The before advice declaration effectively says signal
+ an error for any calls to register that are not within the factory
+ methods.</para>
+
+ </sect2>
+
+ <sect2 id="configurationmanagement" xreflabel="Configuration Management">
+ <title>Configuration Management</title>
+ <indexterm>
+ <primary>configuration management</primary>
+ </indexterm>
+
+ <para>Configuration management for aspects can be handled using a variety
+ of make-file like techniques. To work with optional aspects, the
+ programmer can simply define their make files to either include the
+ aspect in the call to the AspectJ compiler or not, as desired.</para>
+
+ <para>Developers who want to be certain that no aspects are included in
+ the production build can do so by configuring their make files so that
+ they use a traditional Java compiler for production builds. To make it
+ easy to write such make files, the AspectJ compiler has a command-line
+ interface that is consistent with ordinary Java compilers.</para>
+ </sect2>
+
+ </sect1>
+
+ <sect1 id="productionaspects" xreflabel="Production Aspects">
+ <title>Production Aspects</title>
+ <indexterm>
+ <primary>aspect</primary>
+ <secondary>production</secondary>
+ </indexterm>
+
+ <para>This section presents examples of aspects that are inherently
+ intended to be included in the production builds of an application.
+ Production aspects tend to add functionality to an application rather
+ than merely adding more visibility of the internals of a program. Again,
+ we begin with name-based aspects and follow with property-based aspects.
+ Name-based production aspects tend to affect only a small number of
+ methods. For this reason, they are a good next step for projects
+ adopting AspectJ. But even though they tend to be small and simple, they
+ can often have a significant effect in terms of making the program easier
+ to understand and maintain.</para>
+
+ <sect2>
+ <title>Change Monitoring</title>
+ <indexterm><primary>change monitoring</primary></indexterm>
+
+ <para>The first example production aspect shows how one might implement
+ some simple functionality where it is problematic to try and do it
+ explicitly. It supports the code that refreshes the display. The role
+ of the aspect is to maintain a dirty bit indicating whether or not an
+ object has moved since the last time the display was refreshed.</para>
+
+ <para>Implementing this functionality as an aspect is straightforward.
+ The <function>testAndClear</function> method is called by the display
+ code to find out whether a figure element has moved recently. This
+ method returns the current state of the dirty flag and resets it to
+ false. The pointcut <function>move</function> captures all the method
+ calls that can move a figure element. The after advice on
+ <function>move</function> sets the dirty flag whenever an object
+ moves.</para>
+
+<programlisting><![CDATA[
+aspect MoveTracking {
+
+ private static boolean dirty = false;
+
+ public static boolean testAndClear() {
+ boolean result = dirty;
+ dirty = false;
+ return result;
+ }
+
+ pointcut move(): call(void FigureElement.setXY(int, int)) ||
+ call(void Line.setP1(Point)) ||
+ call(void Line.setP2(Point)) ||
+ call(void Point.setX(int)) ||
+ call(void Point.setY(int));
+
+ after() returning: move() {
+ dirty = true;
+ }
+}
+]]></programlisting>
+
+ <para>Even this simple example serves to illustrate some of the important
+ benefits of using AspectJ in production code. Consider implementing
+ this functionality with ordinary Java: there would likely be a helper
+ class that contained the <literal>dirty</literal> flag, the
+ <function>testAndClear</function> method, as well as a
+ <function>setFlag</function> method. Each of the methods that could
+ move a figure element would include a call to the
+ <function>setFlag</function> method. Those calls, or rather the concept
+ that those calls should happen at each move operation, are the
+ crosscutting concern in this case. </para>
+
+ <para>The AspectJ implementation has several advantages over the standard
+ implementation:</para>
+
+ <para><emphasis>The structure of the crosscutting concern is captured
+ explicitly.</emphasis> The moves pointcut clearly states all the
+ methods involved, so the programmer reading the code sees not just
+ individual calls to <literal>setFlag</literal>, but instead sees the
+ real structure of the code. The IDE support included with AspectJ
+ automatically reminds the programmer that this aspect advises each of
+ the methods involved. The IDE support also provides commands to jump
+ to the advice from the method and vice-versa.</para>
+
+ <para><emphasis>Evolution is easier.</emphasis> If, for example, the
+ aspect needs to be revised to record not just that some figure element
+ moved, but rather to record exactly which figure elements moved, the
+ change would be entirely local to the aspect. The pointcut would be
+ updated to expose the object being moved, and the advice would be
+ updated to record that object. The paper <citetitle>An Overview of
+ AspectJ</citetitle>, presented at ECOOP 2001, presents a detailed
+ discussion of various ways this aspect could be expected to
+ evolve.)</para>
+
+ <para><emphasis>The functionality is easy to plug in and out.</emphasis>
+ Just as with development aspects, production aspects may need to be
+ removed from the system, either because the functionality is no longer
+ needed at all, or because it is not needed in certain configurations of
+ a system. Because the functionality is modularized in a single aspect
+ this is easy to do.</para>
+
+ <para><emphasis>The implementation is more stable.</emphasis> If, for
+ example, the programmer adds a subclass of <classname>Line</classname>
+ that overrides the existing methods, this advice in this aspect will
+ still apply. In the ordinary Java implementation the programmer would
+ have to remember to add the call to <function>setFlag</function> in the
+ new overriding method. This benefit is often even more compelling for
+ property-based aspects (see the section <xref
+ linkend="consistentbehavior"/>). </para>
+ </sect2>
+
+ <sect2>
+ <title>Context Passing</title>
+
+ <para>The crosscutting structure of context passing can be a significant
+ source of complexity in Java programs. Consider implementing
+ functionality that would allow a client of the figure editor (a program
+ client rather than a human) to set the color of any figure elements
+ that are created. Typically this requires passing a color, or a color
+ factory, from the client, down through the calls that lead to the
+ figure element factory. All programmers are familiar with the
+ inconvenience of adding a first argument to a number of methods just to
+ pass this kind of context information.</para>
+
+ <para>Using AspectJ, this kind of context passing can be implemented in a
+ modular way. The following code adds after advice that runs only when
+ the factory methods of <classname>Figure</classname> are called in the
+ control flow of a method on a
+ <classname>ColorControllingClient</classname>. </para>
+
+<programlisting><![CDATA[
+aspect ColorControl {
+
+ pointcut CCClientCflow(ColorControllingClient client):
+ cflow(call(* * (..)) && target(client));
+
+ pointcut make(): call(FigureElement Figure.make*(..));
+
+ after (ColorControllingClient c) returning (FigureElement fe):
+ make() && CCClientCflow(c) {
+
+ fe.setColor(c.colorFor(fe));
+ }
+}]]></programlisting>
+
+ <para>This aspect affects only a small number of methods, but note that
+ the non-AOP implementation of this functionality might require editing
+ many more methods, specifically, all the methods in the control flow
+ from the client to the factory. This is a benefit common to many
+ property-based aspects while the aspect is short and affects only a
+ modest number of benefits, the complexity the aspect saves is
+ potentially much larger.</para>
+
+ </sect2>
+
+ <sect2 id="consistentbehavior" xreflabel="Providing Consistent Behavior">
+ <title>Providing Consistent Behavior</title>
+
+ <para>This example shows how a property-based aspect can be used to
+ provide consistent handling of functionality across a large set of
+ operations. This aspect ensures that all public methods of the
+ <literal>com.xerox</literal> package log any errors (a kind of
+ throwable, different from Exception) they throw to their caller. The
+ <function>publicMethodCall</function> pointcut captures the public
+ method calls of the package, and the after advice runs whenever one of
+ those calls returns throwing an exception. The advice logs the
+ exception and then the throw resumes.</para>
+
+ <programlisting><![CDATA[
+aspect PublicErrorLogging {
+ Log log = new Log();
+
+ pointcut publicMethodCall(): call(public * com.xerox.*.*(..));
+
+ after() throwing (Error e): publicMethodCall() { log.write(e); }
+}]]></programlisting>
+
+ <para>In some cases this aspect can log an exception twice. This happens
+ if code inside the <literal>com.xerox</literal> package itself calls a
+ public method of the package. In that case this code will log the error
+ at both the outermost call into the <literal>com.xerox</literal>
+ package and the re-entrant call. The <function>cflow</function>
+ primitive pointcut can be used in a nice way to exclude these
+ re-entrant calls:</para>
+
+ <programlisting><![CDATA[
+after() throwing (Error e): publicMethodCall() &&
+ !cflow(publicMethodCall()) {
+ log.write(e);
+}]]></programlisting>
+
+
+ <para>The following aspect is taken from work on the AspectJ compiler.
+ The aspect advises about 35 methods in the
+ <classname>JavaParser</classname> class. The individual methods handle
+ each of the different kinds of elements that must be parsed. They have
+ names like <function>parseMethodDec</function>,
+ <function>parseThrows</function>, and
+ <function>parseExpr</function>.</para>
+
+ <programlisting><![CDATA[
+aspect ContextFilling {
+ pointcut parse(JavaParser jp):
+ call(* JavaParser.parse*(..))
+ && target(jp)
+ && !call(Stmt parseVarDec(boolean)); // var decs
+ // are tricky
+
+ around(JavaParser jp) returns ASTObject: parse(jp) {
+ Token beginToken = jp.peekToken();
+ ASTObject ret = proceed(jp);
+ if (ret != null) jp.addContext(ret, beginToken);
+ return ret;
+ }
+}]]></programlisting>
+
+ <para>This example exhibits a property found in many aspects with large
+ property-based pointcuts. In addition to a general property based
+ pattern <literal>call(* JavaParser.parse*(..))</literal> it includes an
+ exception to the pattern <literal>!call(Stmt
+ parseVarDec(boolean))</literal>. The exclusion of
+ <function>parseVarDec</function> happens because the parsing of
+ variable declarations in Java is too complex to fit with the clean
+ pattern of the other <function>parse*</function> methods. Even with the
+ explicit exclusion this aspect is a clear expression of a clean
+ crosscutting modularity. Namely that all <function>parse*</function>
+ methods that return <classname>ASTObjects</classname>, except for
+ <function>parseVarDec</function> share a common behavior for
+ establishing the parse context of their result. </para>
+
+ <para>The process of writing an aspect with a large property-based
+ pointcut, and of developing the appropriate exceptions can clarify the
+ structure of the system. This is especially true, as in this case, when
+ refactoring existing code to use aspects. When we first looked at the
+ code for this aspect, we were able to use the IDE support provided in
+ AJDE for JBuilder to see what methods the aspect was advising compared
+ to our manual coding. We quickly discovered that there were a dozen
+ places where the aspect advice was in effect but we had not manually
+ inserted the required functionality. Two of these were bugs in our
+ prior non-AOP implementation of the parser. The other ten were needless
+ performance optimizations. So, here, refactoring the code to express
+ the crosscutting structure of the aspect explicitly made the code more
+ concise and eliminated latent bugs.</para>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1>
+ <title>Static Crosscutting: Introduction</title>
+ <indexterm><primary>introduction</primary></indexterm>
+
+ <para>Up until now we have only seen constructs that allow us to
+ implement dynamic crosscutting, crosscutting that changes the way a
+ program executes. AspectJ also allows us to implement static
+ crosscutting, crosscutting that affects the static structure of our
+ progams. This is done using forms called introduction.</para>
+
+ <para>An <emphasis>introduction</emphasis> is a member of an aspect, but
+ it defines or modifies a member of another type (class). With
+ introduction we can</para>
+ <itemizedlist>
+ <listitem>
+ <para>add methods to an existing class</para>
+ </listitem>
+ <listitem>
+ <para>add fields to an existing class</para>
+ </listitem>
+ <listitem>
+ <para>extend an existing class with another</para>
+ </listitem>
+ <listitem>
+ <para>implement an interface in an existing class</para>
+ </listitem>
+ <listitem>
+ <para>convert checked exceptions into unchecked exceptions</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Suppose we want to change the class
+ <classname>Point</classname> to support cloning. By using introduction,
+ we can add that capability. The class itself doesn't change, but its
+ users (here the method <function>main</function>) may. In the example
+ below, the aspect <classname>CloneablePoint</classname> does three
+ things: </para>
+ <orderedlist>
+ <listitem>
+ <para>declares that the class
+ <classname>Point</classname> implements the interface
+ <classname>Cloneable</classname>,</para>
+ </listitem>
+ <listitem>
+ <para>declares that the methods in <classname>Point</classname> whose
+ signature matches <literal>Object clone()</literal> should have
+ their checked exceptions converted into unchecked exceptions,
+ and</para>
+ </listitem>
+ <listitem>
+ <para>adds a method that overrides the method
+ <function>clone</function> in <classname>Point</classname>, which
+ was inherited from <classname>Object</classname>.</para>
+ </listitem>
+ </orderedlist>
+
+ <programlisting>
+class Point {
+ private int x, y;
+
+ Point(int x, int y) { this.x = x; this.y = y; }
+
+ int getX() { return this.x; }
+ int getY() { return this.y; }
+
+ void setX(int x) { this.x = x; }
+ void setY(int y) { this.y = y; }
+
+ public static void main(String[] args) {
+
+ Point p = new Point(3,4);
+ Point q = (Point) p.clone();
+ }
+}
+
+aspect CloneablePoint {
+ declare parents: Point implements Cloneable;
+
+ declare soft: CloneNotSupportedException: execution(Object clone());
+
+ Object Point.clone() { return super.clone(); }
+}</programlisting>
+
+ <para>Introduction is a powerful mechanism for capturing crosscutting
+ concerns because it not only changes the behavior of components in an
+ application, but also changes their relationship.</para>
+
+ </sect1>
+
+ <sect1>
+ <title>Conclusion</title>
+
+ <para>AspectJ is a simple and practical aspect-oriented extension to
+ Java. With just a few new constructs, AspectJ provides support for modular
+ implementation of a range of crosscutting concerns.</para>
+
+ <para> Adoption of AspectJ into an existing Java development project can be
+ a straightforward and incremental task. One path is to begin by
+ using only development aspects, going on to using production aspects and
+ then reusable aspects after building up experience with AspectJ. Adoption
+ can follow other paths as well. For example, some developers will
+ benefit from using production aspects right away. Others may be able to
+ write clean reusable aspects almost right away.</para>
+
+ <para>AspectJ enables both name-based and property based crosscutting.
+ Aspects that use name-based crosscutting tend to affect a small number of
+ other classes. But despite their small scale, they can often eliminate
+ significant complexity compared to an ordinary Java implementation.
+ Aspects that use property-based crosscutting can have small or large
+ scale.</para>
+
+ <para>Using AspectJ results in clean well-modularized implementations of
+ crosscutting concerns. When written as an AspectJ aspect the structure
+ of a crosscutting concern is explicit and easy to understand. Aspects
+ are also highly modular, making it possible to develop plug-and-play
+ implementations of crosscutting functionality.</para>
+
+ <para>AspectJ provides more functionality than was covered by this short
+ introduction. The next chapter, <xref linkend="aspectjlanguage"/>, covers
+ in detail all the features of the AspectJ language. The following
+ chapter, <xref linkend="examples"/>, then presents some carefully chosen
+ examples that show you how AspectJ might be used. We recommend that you
+ read the next two chapters carefully before deciding to adopt AspectJ
+ into a project.
+ </para>
+
+ </sect1>
+
+</chapter>
+
+<!--
+Local variables:
+compile-command: "build.sh"
+fill-column: 79
+sgml-local-ecat-files: progguide.ced
+sgml-parent-document:("progguide.xml" "book" "chapter")
+End:
+-->
diff --git a/docs/progGuideDB/glossary.xml b/docs/progGuideDB/glossary.xml
new file mode 100644
index 000000000..4516ce2bd
--- /dev/null
+++ b/docs/progGuideDB/glossary.xml
@@ -0,0 +1,192 @@
+<appendix id="glossary" xreflabel="Glossary">
+
+ <title>Glossary</title>
+
+ <glosslist>
+
+<!--
+ <glossentry><glossterm>
+</glossterm>
+ <glossdef>
+ <para></para>
+ </glossdef>
+ </glossentry>
+
+-->
+
+ <glossentry><glossterm>
+advice</glossterm>
+ <glossdef>
+ <para>Code, similar to a method, that is executed when a join
+ point<emphasis></emphasis> is reached. There are three kinds of
+ advice: before advice that runs when a join point is reached, but
+ before the method in question executes, after advice that executes
+ after the method body executes, but before control returns to the
+ caller, and around advice that runs before and after the method in
+ question runs, and also has explicit control over whether the method
+ is run at all.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+AOP</glossterm>
+ <glossdef>
+ <para>See <emphasis>aspect-oriented programming</emphasis>.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+aspect</glossterm>
+ <glossdef>
+ <para>A modular unit of crosscutting implementation in
+ <emphasis>aspect-oriented programming</emphasis>, just as classes are
+ the modular unit of implementation in object-oriented
+ programming.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+aspect-oriented programming</glossterm>
+ <glossdef>
+ <para>A type or style of programming that explicitly takes into
+ account <emphasis>crosscutting concerns</emphasis>, just as
+ object-oriented programming explicitly takes into account classes and
+ objects. </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+crosscutting concerns</glossterm>
+ <glossdef>
+ <para>Issues or programmer concerns that are not local to the natural
+ unit of modularity. </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+dynamic context</glossterm>
+ <glossdef>
+ <para>The state of a program while it is executing. Contrast with
+ <emphasis>lexical context</emphasis>.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+join point</glossterm>
+ <glossdef>
+ <para> A well-defined instant in the execution of a program. In
+ AspectJ, join points are also principled, i.e. not every possible
+ instance in the execution of a program is a potential join point.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+lexical context</glossterm>
+ <glossdef>
+ <para>The state of a program as it is written. Contrast with
+ <emphasis>dynamic context</emphasis>.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+name-based pointcut designator</glossterm>
+ <glossdef>
+ <para>A type of pointcut designator that enumerates and composes
+ explicitly named join points. For example,</para>
+ <programlisting>
+pointcut move():
+ call(void FigureElement.setXY(int,int)) ||
+ call(void Point.setX(int)) ||
+ call(void Point.setY(int)) ||
+ call(void Line.setP1(Point)) ||
+ call(void Line.setP2(Point));</programlisting>
+ <para>is a pointcut designator that explicitly names five join
+ points. See also <emphasis>property-based pointcut
+ designator</emphasis>.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+pointcut</glossterm>
+ <glossdef>
+ <para>A collection of join points.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+pointcut designator</glossterm>
+ <glossdef>
+ <para>The name of a pointcut, or an expression which identifies a
+ pointcut. Pointcut designators can be primitive or composite.
+ Composite pointcut designators are primitive pointcut designators
+ composed using the operators <literal>||</literal>,
+ <literal>&amp;&amp;<literal>, and </literal>!</literal>. See also
+ <emphasis>name-based pointcut designator</emphasis> and
+ <emphasis>property-based pointcut sesignator</emphasis>. </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+post-condition</glossterm>
+ <glossdef>
+ <para>A test or assertion that must be true after a method has
+ executed.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+pre-condition</glossterm>
+ <glossdef>
+ <para>A test or assertion that must be true when a method is
+ called.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+property-based pointcut designator</glossterm>
+ <glossdef>
+ <para>A type of pointcut designator that specifies pointcuts in terms
+ of the properties of methods rather than just their names. For
+ example,</para>
+ <programlisting>
+call(public * Figure.*(..))</programlisting>
+ <para>specifies all the public methods in the class
+ <classname>Figure</classname> regardless of the type and number of
+ their arguments or return type. See also <emphasis>name-based
+ pointcut designator</emphasis>.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+reusable aspect</glossterm>
+ <glossdef>
+ <para>An aspect that can be extended or inherited from.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+signature</glossterm>
+ <glossdef>
+ <para>The number, order and type of the arguments to a method.</para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry><glossterm>
+<literal>thisJoinPoint</literal></glossterm>
+ <glossdef>
+ <para>The special variable that identifies the current join point
+ when a non-static join point is reached.</para>
+ </glossdef>
+ </glossentry>
+
+ </glosslist>
+
+</appendix>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.sgml" "book" "appendix") -->
+<!-- End: -->
diff --git a/docs/progGuideDB/idioms.xml b/docs/progGuideDB/idioms.xml
new file mode 100644
index 000000000..5898dbd9e
--- /dev/null
+++ b/docs/progGuideDB/idioms.xml
@@ -0,0 +1,104 @@
+<chapter id="idioms" xreflabel="Idioms">
+ <title>Idioms</title>
+
+ <sect1><!-- About this Chapter -->
+ <title>About this Chapter</title>
+
+ <para>This chapter consists of very short snippets of AspectJ code,
+ typically pointcuts, that are particularly evocative or useful.
+ This section is a work in progress.
+ </para>
+
+ <para> Here's an example of how to enfore a rule that code in the java.sql
+ package can only be used from one particular package in your system. This
+ doesn't require any access to code in the java.sql package.
+ </para>
+
+<programlisting><![CDATA[
+/* Any call to methods or constructors in java.sql */
+pointcut restrictedCall():
+ call(* java.sql.*.*(..)) || call(java.sql.*.new(..));
+
+/* Any code in my system not in the sqlAccess package */
+pointcut illegalSource():
+ within(com.foo..*) && !within(com.foo.sqlAccess.*);
+
+declare error: restrictedCall() && illegalSource():
+ "java.sql package can only be accessed from com.foo.sqlAccess";
+]]></programlisting>
+
+ <para>Any call to an instance of a subtype of AbstractFacade whose class is
+ not exactly equal to AbstractFacade:</para>
+
+<programlisting><![CDATA[
+pointcut nonAbstract(AbstractFacade af):
+ call(* *(..))
+ && target(af)
+ && !if(af.getClass() == AbstractFacade.class);
+]]></programlisting>
+
+ <para> If AbstractFacade is an abstract class or an interface, then every
+ instance must be of a subtype and you can replace this with: </para>
+
+<programlisting><![CDATA[
+pointcut nonAbstract(AbstractFacade af):
+ call(* *(..))
+ && target(af);
+]]></programlisting>
+
+ <para> Any call to a method which is defined by a subtype of
+ AbstractFacade, but which isn't defined by the type AbstractFacade itself:
+ </para>
+
+<programlisting><![CDATA[
+pointcut callToUndefinedMethod():
+ call(* AbstractFacade+.*(..))
+ && !call(* AbstractFacade.*(..));
+]]></programlisting>
+
+ <para> The execution of a method that is defined in the source code for a
+ type that is a subtype of AbstractFacade but not in AbstractFacade itself:
+ </para>
+
+<programlisting><![CDATA[
+pointcut executionOfUndefinedMethod():
+ execution(* *(..))
+ && within(AbstractFacade+)
+ && !within(AbstractFacade)
+]]></programlisting>
+
+ <para>To use a per-class variable declared on many classes,
+ you can defer initialization until you are in a non-static instance context
+ so you can refer to the particular class member. If you want to use
+ it from advice (without knowing the particular class at compile-time),
+ you can declare a method on the type.
+ </para>
+
+<programlisting><![CDATA[
+aspect Logging {
+
+ //...
+
+ /** per-Loggable-class reference to per-class Logger */
+ static private Logger Loggable+.staticLogger;
+
+ /** instance getter for static logger (lazy construction) */
+ public Logger Loggable+.getLogger() { // XXX make private to aspect?
+ if (null == staticLogger) {
+ staticLogger = Logger.getLoggerFor(getClass());
+ }
+ return staticLogger;
+ }
+
+ /** when logging and logger enabled, log the target and join point */
+ before(Loggable loggable) : target(loggable) && logging() {
+ Logger logger = loggable.getLogger();
+ if (logger.enabled()) {
+ logger.log(loggable + " at " + thisJoinPoint);
+ }
+ }
+}
+]]></programlisting>
+
+ </sect1>
+</chapter>
diff --git a/docs/progGuideDB/language.xml b/docs/progGuideDB/language.xml
new file mode 100644
index 000000000..0f5e23561
--- /dev/null
+++ b/docs/progGuideDB/language.xml
@@ -0,0 +1,1226 @@
+<chapter id="aspectjlanguage" xreflabel="The AspectJ Language">
+
+ <title>The AspectJ Language</title>
+
+ <sect1>
+ <title>Introduction</title>
+
+ <para>The previous chapter, <xref linkend="gettingstarted"/>, was a brief
+ overview of the AspectJ language. You should read this chapter to
+ understand AspectJ's syntax and semantics. It covers the same material as
+ the previous chapter, but more completely and in much more detail.
+ </para>
+
+ <para>We will start out by looking at an example aspect that we'll build
+ out of a pointcut, an introduction, and two pieces of advice. This
+ example aspect will gives us something concrete to talk about.</para>
+
+ </sect1>
+
+ <sect1 id="AnatomyOfAnAspect">
+ <title>The Anatomy of an Aspect</title>
+
+ <para>
+ This lesson explains the parts of AspectJ's aspects. By reading this
+ lesson you will have an overview of what's in an aspect and you will be
+ exposed to the new terminology introduced by AspectJ.
+ </para>
+
+ <sect2>
+ <title>An Example Aspect</title>
+
+ <para>
+ Here's an example of an aspect definition in AspectJ:
+ </para>
+
+ <programlisting><![CDATA[
+ 1 aspect FaultHandler {
+ 2
+ 3 private boolean Server.disabled = false;
+ 4
+ 5 private void reportFault() {
+ 6 System.out.println("Failure! Please fix it.");
+ 7 }
+ 8
+ 9 public static void fixServer(Server s) {
+10 s.disabled = false;
+11 }
+12
+13 pointcut services(Server s): target(s) && call(public * *(..));
+14
+15 before(Server s): services(s) {
+16 if (s.disabled) throw new DisabledException();
+17 }
+18
+19 after(Server s) throwing (FaultException e): services(s) {
+20 s.disabled = true;
+21 reportFault();
+22 }
+23 }
+]]></programlisting>
+
+ <para>
+ The <literal>FaultHandler</literal> consists of one variable introduced
+ onto <literal>Server</literal> (line 03), two methods (lines 05-07
+ and 09-11), one pointcut (line 13), and two pieces of advice (lines
+ 15-17 and 19-22).
+ </para>
+
+ <para>
+ This covers the basics of what aspects can contain. In general, aspects
+ consist of an association with other program entities, ordinary
+ variables and methods, pointcuts, introductions, and advice, where
+ advice may be before, after or around advice. The remainder of this
+ lesson focuses on those crosscut-related constructs.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Pointcuts</title>
+
+ <para>
+ AspectJ's pointcuts define collections of events, i.e. interesting
+ points in the execution of a program. These events, or points in the
+ execution, can be method or constructor invocations and executions,
+ handling of exceptions, field assignments and accesses, etc. Take, for
+ example, the pointcut declaration in line 13:
+ </para>
+
+<programlisting><![CDATA[
+pointcut services(Server s): target(s) && call(public * *(..))
+]]></programlisting>
+
+ <para>
+ This pointcut, named <literal>services</literal>, picks out those points
+ in the execution of the program when instances of the
+ <literal>Server</literal> class have their public methods called.
+ </para>
+
+ <para>
+ The idea behind this pointcut in the <literal>FaultHandler</literal>
+ aspect is that fault-handling-related behavior must be triggered on the
+ calls to public methods. For example, the server may be unable to
+ proceed with the request because of some fault. The calls of those
+ methods are, therefore, interesting events for this aspect, in the
+ sense that certain fault-related things will happen when these events
+ occur.
+ </para>
+
+ <para>
+ Part of the context in which the events occur is exposed by the formal
+ parameters of the pointcut. In this case, that consists of objects of
+ type server. That formal parameter is then being used on the right
+ hand side of the declaration in order to identify which events the
+ pointcut refers to. In this case, a pointcut picking out join points
+ where a Server is the target of some operation (target(s)) is being
+ composed (<literal><![CDATA[&&]]></literal>, meaning and) with a
+ pointcut picking out call join points (call(...)). The calls are
+ identified by signatures that can include wild cards. In this case,
+ there are wild cards in the return type position (first *), in the name
+ position (second *) and in the argument list position (..); the only
+ concrete information is given by the qualifier public.
+ </para>
+
+ <sect3>
+ <title>What else?</title>
+
+ <para>
+ Pointcuts define arbitrarily large sets of points in the execution
+ of a program. But they use only a finite number of
+ <emphasis>kinds</emphasis> of points. Those kinds of points
+ correspond to some of the most important concepts in Java. Here is
+ an incomplete list: method invocation, method execution, exception
+ handling, instantiation, constructor execution. Each of these has a
+ specific syntax that you will learn about in other parts of this
+ guide.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Advice</title>
+
+ <para>
+ Advice defines pieces of aspect implementation that execute at join
+ points picked out by a pointcut. For example, the advice in lines 15-17
+ specifies that the following piece of code
+ </para>
+
+<programlisting><![CDATA[
+{
+ if (s.disabled) throw new DisabledException();
+}
+]]></programlisting>
+
+ <para>
+ is executed when instances of the Server class have their public
+ methods called, as specified by the pointcut services. More
+ specifically, it runs when those calls are made, just before the
+ corresponding methods are executed.
+ </para>
+
+ <para>
+ The advice in lines 19-22 defines another piece of implementation
+ that is executed on the same pointcut:
+ </para>
+
+<programlisting><![CDATA[
+{
+ s.disabled = true;
+ reportFault();
+}
+]]></programlisting>
+
+ <para>
+ But this second method executes whenever those operations throw
+ exception of type <literal>FaultException</literal>.
+ </para>
+
+ <sect3>
+ <title>What else?</title>
+ <para>
+ There are two other variations of after advice: upon successful
+ return and upon return, either successful or with an exception.
+ There is also a third kind of advice called around. You will see
+ those in other parts of this guide.
+ </para>
+ </sect3>
+ </sect2>
+
+ </sect1>
+
+ <sect1>
+ <title>Join Points and Pointcuts</title>
+
+ <para>
+ Consider the following Java class:
+ </para>
+
+<programlisting><![CDATA[
+class Point {
+ private int x, y;
+
+ Point(int x, int y) { this.x = x; this.y = y; }
+
+ void setX(int x) { this.x = x; }
+ void setY(int y) { this.y = y; }
+
+ int getX() { return x; }
+ int getY() { return y; }
+}
+]]></programlisting>
+
+ <para>
+ In order to get an intuitive understanding of AspectJ's pointcuts, let's
+ go back to some of the basic principles of Java. Consider the following a
+ method declaration in class Point:
+ </para>
+
+<programlisting><![CDATA[
+void setX(int x) { this.x = x; }
+]]></programlisting>
+
+ <para>
+ What this piece of program states is that when an object of type Point
+ has a method called setX with an integer as the argument called on it,
+ then the method body { this.x = x; } is executed. Similarly, the
+ constructor given in that class states that when an object of type Point
+ is instantiated through a constructor with two integers as arguments,
+ then the constructor body { this.x = x; this.y = y; } is executed.
+ </para>
+
+ <para>
+ One pattern that emerges from these descriptions is when something
+ happens, then something gets executed. In object-oriented programs, there
+ are several kinds of "things that happen" that are determined by the
+ language. We call these the join points of Java. Join points comprised
+ method calls, method executions, instantiations, constructor executions,
+ field references and handler executions. (See the quick reference for
+ complete listing.)
+ </para>
+
+ <para>
+ Pointcuts pick out these join points. For example, the pointcut
+ </para>
+
+<programlisting><![CDATA[
+pointcut setter(): target(Point) &&
+ (call(void setX(int)) ||
+ call(void setY(int)));
+]]></programlisting>
+
+ <para>
+ describes the calls to <literal>setX(int)</literal> or
+ <literal>setY(int)</literal> methods of any instance of Point. Here's
+ another example:
+ </para>
+
+<programlisting><![CDATA[
+pointcut ioHandler(): within(MyClass) && handler(IOException);
+]]></programlisting>
+
+ <para>
+ This pointcut picks out the join points at which exceptions of type
+ IOException are handled inside the code defined by class MyClass.
+ </para>
+
+ <para>
+ Pointcuts consist of a left-hand side and a right-hand side, separated by
+ a colon. The left-hand side defines the pointcut name and the pointcut
+ parameters (i.e. the data available when the events happen). The
+ right-hand side defines the events in the pointcut.
+ </para>
+
+ <para>
+ Pointcuts can then be used to define aspect code in advice, as we will
+ see later. But first let's see what types of events can be captured and
+ how they are described in AspectJ.
+ </para>
+
+ <sect2>
+ <title>Designators</title>
+
+ <para>
+ Here are examples of designators of
+ </para>
+ <glosslist>
+
+ <glossentry>
+ <glossterm>when a particular method body executes</glossterm>
+ <glossdef>
+ <para>
+ <literal>execution(void Point.setX(int))</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when a method is called</glossterm>
+ <glossdef>
+ <para>
+ <literal>call(void Point.setX(int))</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when an exception handler executes</glossterm>
+ <glossdef>
+ <para>
+ <literal>handler(ArrayOutOfBoundsException)</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when the object currently executing
+ (i.e. <literal>this</literal>) is of type <literal>SomeType</literal></glossterm>
+ <glossdef>
+ <para>
+ <literal>this(SomeType)</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when the target object is of type
+ <literal>SomeType</literal></glossterm>
+ <glossdef>
+ <para>
+ <literal>target(SomeType)</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when the executing code belongs to
+ class <literal>MyClass</literal></glossterm>
+ <glossdef>
+ <para>
+ <literal>within(MyClass)</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>when the join point is in the control flow of a call to a
+ <literal>Test</literal>'s no-argument <literal>main</literal> method
+ </glossterm>
+ <glossdef>
+ <para>
+ <literal>cflow(void Test.main())</literal>
+ </para>
+ </glossdef>
+ </glossentry>
+
+
+ </glosslist>
+
+ <para>
+ Designators compose through the operations <literal>or</literal>
+ ("<literal>||</literal>"), <literal>and</literal>
+ ("<literal><![CDATA[&&]]></literal>") and <literal>not</literal>
+ ("<literal>!</literal>").
+ </para>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ It is possible to use wildcards. So
+ <orderedlist>
+ <listitem>
+ <para>
+ <literal>execution(* *(..))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>call(* set(..))</literal>
+ </para>
+ </listitem>
+ </orderedlist>
+ means (1) all the executions of methods with any return and
+ parameter types and (2) method calls of set methods with any
+ return and parameter types -- in case of overloading there may be
+ more than one; this designator picks out all of them.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You can select elements based on types. For example,
+ <orderedlist>
+ <listitem>
+ <para>
+ <literal>execution(int *())</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>call(* setY(long))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>call(* Point.setY(int))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>call(*.new(int, int))</literal>
+ </para>
+ </listitem>
+
+ </orderedlist>
+ means (1) all executions of methods with no parameters, returning
+ an <literal>int</literal> (2) the calls of
+ <literal>setY</literal> methods that take a
+ <literal>long</literal> as an argument, regardless of their return
+ type or defining type, (3) the calls of class
+ <literal>Point</literal>'s <literal>setY</literal> methods that
+ take an <literal>int</literal> as an argument, regardless of the
+ return type, and (4) the calls of all classes' constructors that
+ take two <literal>int</literal>s as arguments.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You can compose designators. For example,
+ <orderedlist>
+ <listitem>
+ <para>
+ <literal>target(Point) <![CDATA[&&]]> call(int *())</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>call(* *(..)) <![CDATA[&&]]> (within(Line) || within(Point))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>within(*) <![CDATA[&&]]> execution(*.new(int))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>this(*) <![CDATA[&&]]> !this(Point) <![CDATA[&&]]>
+ call(int *(..))</literal>
+ </para>
+ </listitem>
+ </orderedlist>
+
+ means (1) all calls to methods received by instances of class
+ <literal>Point</literal>, with no parameters, returning an
+ <literal>int</literal>, (2) calls to any method where the call is
+ made from the code in <literal>Point</literal>'s or
+ <literal>Line</literal>'s type declaration, (3) executions of
+ constructors of all classes, that take an <literal>int</literal> as
+ an argument, and
+ (4) all method calls of any method returning an
+ <literal>int</literal>, from all objects except
+ <literal>Point</literal> objects to any other objects.
+
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ You can select methods and constructors based on their modifiers
+ and on negations of modifiers. For example, you can say:
+ <orderedlist>
+ <listitem>
+ <para>
+ <literal>call(public * *(..))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>execution(!static * *(..))</literal>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal> execution(public !static * *(..))</literal>
+ </para>
+ </listitem>
+
+ </orderedlist>
+ which means (1) all invocation of public methods, (2) all
+ executions of non-static methods, and (3) all signatures of
+ the public, non-static methods.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Designators can also deal with interfaces. For example, given the
+ interface </para>
+
+ <programlisting><![CDATA[
+interface MyInterface { ... }]]></programlisting>
+
+ <para> the designator <literal>call(* MyInterface.*(..))</literal>
+ picks out the call join points for methods defined by the interface
+ <literal>MyInterface</literal> (or its superinterfaces).
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </sect2>
+
+ <sect2>
+ <title>call vs. execution</title>
+
+ <para>
+ When methods and constructors run, there are two interesting times
+ associated with them. That is when they are called, and when they
+ actually execute.
+ </para>
+
+ <para>
+ AspectJ exposes these times as call and execution join points,
+ respectively, and allows them to be picked out specifically by call and
+ execution pointcuts.
+ </para>
+
+ <para>
+ So what's the difference between these times? Well, there are a number
+ of differences:
+ </para>
+
+ <para>
+ Firstly, the lexical pointcut declarations <literal>within</literal>
+ and <literal>withincode</literal> match differently. At a call join
+ point, the enclosing text is that of the call site. This means that
+ This means that <literal>call(void m()) <![CDATA[&&]]> within(void m())</literal>
+ will only capture recursive calls, for example. At an execution join
+ point, however, the control is already executing the method.
+ </para>
+
+ <para>
+ Secondly, the call join point does not capture super calls to
+ non-static methods. This is because such super calls are different in
+ Java, since they don't behave via dynamic dispatch like other calls to
+ non-static methods.
+ </para>
+
+ <para>
+ The rule of thumb is that if you want to pick a join point that runs
+ when an actual piece of code runs, pick an execution, but if you want
+ to pick one that runs when a particular signature is called, pick a
+ call.
+ </para>
+ </sect2>
+
+
+
+ <sect2>
+ <title>Pointcut composition</title>
+
+ <para>Pointcuts are put together with the operators and (spelled
+ <literal>&amp;&amp;</literal>), or (spelled <literal>||</literal>), and
+ not (spelled <literal>!</literal>). This allows the creation of very
+ powerful pointcuts from the simple building blocks of primitive
+ pointcuts. This composition can be somewhat confusing when used with
+ primitive pointcuts like cflow and cflowbelow. Here's an example:
+ </para>
+
+ <para> <literal>cflow(<replaceable>P</replaceable>)</literal> picks out
+ the join points in the control flow of the join points picked out by
+ <replaceable>P</replaceable>. So, pictorially:
+ </para>
+
+<programlisting>
+ P ---------------------
+ \
+ \ cflow of P
+ \
+</programlisting>
+
+
+ <para>What does <literal>cflow(<replaceable>P</replaceable>) &amp;&amp;
+ cflow(<replaceable>Q</replaceable>)</literal> pick out? Well, it picks
+ out those join points that are in both the control flow of
+ <replaceable>P</replaceable> and in the control flow of
+ <replaceable>Q</replaceable>. So...
+ </para>
+
+<programlisting>
+ P ---------------------
+ \
+ \ cflow of P
+ \
+ \
+ \
+ Q -------------\-------
+ \ \
+ \ cflow of Q \ cflow(P) &amp;&amp; cflow(Q)
+ \ \
+</programlisting>
+
+ <para>Note that <replaceable>P</replaceable> and <replaceable>Q</replaceable> might
+ not have any join points in common... but their control flows might have join
+ points in common.
+ </para>
+
+ <para>But what does <literal>cflow(<replaceable>P</replaceable>
+ &amp;&amp; <replaceable>Q</replaceable>)</literal> mean? Well, it means
+ the control flow of those join points that are both picked out by
+ <replaceable>P</replaceable> picked out by <replaceable>Q</replaceable>.
+ </para>
+
+<programlisting>
+ P &amp;&amp; Q -------------------
+ \
+ \ cflow of (P &amp;&amp; Q)
+ \
+</programlisting>
+
+ <para>and if there are <emphasis>no</emphasis> join points that are both picked by
+ <replaceable>P</replaceable> and picked out by <replaceable>Q</replaceable>,
+ then there's no chance that there are any join points in the control flow of
+ <literal>(<replaceable>P</replaceable> &amp;&amp;
+ <replaceable>Q</replaceable>)</literal>.
+ </para>
+
+ <para>Here's some code that expresses this.
+ </para>
+
+<programlisting><![CDATA[
+public class Test {
+ public static void main(String[] args) {
+ foo();
+ }
+ static void foo() {
+ goo();
+ }
+ static void goo() {
+ System.out.println("hi");
+ }
+}
+
+aspect A {
+
+ pointcut fooPC(): execution(void Test.foo());
+ pointcut gooPC(): execution(void Test.goo());
+ pointcut printPC(): call(void java.io.PrintStream.println(String));
+
+ before(): cflow(fooPC()) && cflow(gooPC()) && printPC() {
+ System.out.println("should occur");
+ }
+
+ before(): cflow(fooPC() && gooPC()) && printPC() {
+ System.out.println("should not occur");
+ }
+
+}
+]]></programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Pointcut Parameters</title>
+
+ <para>
+ Consider, for example, the first pointcut you've seen here,
+ </para>
+
+<programlisting><![CDATA[
+ pointcut setter(): target(Point) &&
+ (call(void setX(int)) ||
+ call(void setY(int)));
+]]></programlisting>
+
+ <para>
+ As we've seen before, the right-hand side of the pointcut picks out the
+ calls to <literal>setX(int)</literal> or <literal>setY(int)</literal>
+ methods where the target is any object of type
+ <literal>Point</literal>. On the left-hand side, the pointcut is given
+ the name "setters" and no parameters. An empty parameter list means
+ that when those events happen no context is immediately available. But
+ consider this other version of the same pointcut:
+ </para>
+
+<programlisting><![CDATA[
+ pointcut setter(Point p): target(p) &&
+ (call(void setX(int)) ||
+ call(void setY(int)));
+]]></programlisting>
+
+ <para>
+ This version picks out exactly the same calls. But in this version, the
+ pointcut has one parameter of type <literal>Point</literal>. This means
+ that when the events described on the right-hand side happen, a
+ <literal>Point</literal> object, named by a parameter named "p", is
+ available. According to the right-hand side of the pointcut, that
+ <literal>Point</literal> object in the pointcut parameters is the
+ object that receives the calls.
+ </para>
+
+ <para>
+ Here's another example that illustrates the flexible mechanism for
+ defining pointcut parameters:
+ </para>
+
+<programlisting><![CDATA[
+ pointcut testEquality(Point p): target(Point) &&
+ args(p) &&
+ call(boolean equals(Object));
+]]></programlisting>
+
+ <para>
+ This pointcut also has a parameter of type <literal>Point</literal>.
+ Similarly to the "setters" pointcut, this means that when the events
+ described on the right-hand side happen, a <literal>Point</literal>
+ object, named by a parameter named "p", is available. But in this case,
+ looking at the right-hand side, we find that the object named in the
+ parameters is not the target <literal>Point</literal> object that receives the
+ call; it's the argument (of type Point) passed to the "equals" method on some other
+ target Point object. If we wanted access to both objects, then the pointcut
+ definition that would define target <literal>Point p1</literal>
+ and argument <literal>Point p2</literal> would be
+ </para>
+
+<programlisting><![CDATA[
+ pointcut testEquality(Point p1, Point p2): target(p1) &&
+ args(p2) &&
+ call(boolean equals(Object));
+]]></programlisting>
+
+ <para>
+ Let's look at another variation of the "setters" pointcut:
+ </para>
+
+<programlisting><![CDATA[
+pointcut setter(Point p, int newval): target(p) &&
+ args(newval) &&
+ (call(void setX(int)) ||
+ call(void setY(int)));
+]]></programlisting>
+
+ <para>
+ In this case, a <literal>Point</literal> object and an integer value
+ are available when the calls happen. Looking at the events definition
+ on the right-hand side, we find that the <literal>Point</literal>
+ object is the object receiving the call, and the integer
+ value is the argument of the method .
+ </para>
+
+ <para>
+ The definition of pointcut parameters is relatively flexible. The most
+ important rule is that when each of those events defined in the
+ right-hand side happen, all the pointcut parameters must be bound to
+ some value. So, for example, the following pointcut definition will
+ result in a compilation error:
+ </para>
+
+<programlisting><![CDATA[
+ pointcut xcut(Point p1, Point p2):
+ (target(p1) && call(void setX(int))) ||
+ (target(p2) && call(void setY(int)));
+]]></programlisting>
+
+ <para>
+ The right-hand side establishes that this pointcut picks out the call
+ join points consisting of the <literal>setX(int)</literal> method
+ called on a point object, or the <literal>setY(int)</literal> method
+ called on a point object. This is fine. The problem is that the
+ parameters definition tries to get access to two point objects. But
+ when <literal>setX(int)</literal> is called on a point object, there is
+ no other point object to grab! So in that case, the parameter
+ <literal>p2</literal> is unbound, and hence, the compilation error.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Example: <literal>HandleLiveness</literal></title>
+
+ <para>
+ The example below consists of two object classes (plus an exception
+ class) and one aspect. Handle objects delegate their public, non-static
+ operations to their <literal>Partner</literal> objects. The aspect
+ <literal>HandleLiveness</literal> ensures that, before the delegations,
+ the partner exists and is alive, or else it throws an exception.</para>
+
+<programlisting><![CDATA[
+ class Handle {
+ Partner partner = new Partner();
+
+ public void foo() { partner.foo(); }
+ public void bar(int x) { partner.bar(x); }
+
+ public static void main(String[] args) {
+ Handle h1 = new Handle();
+ h1.foo();
+ h1.bar(2);
+ }
+ }
+
+ class Partner {
+ boolean isAlive() { return true; }
+ void foo() { System.out.println("foo"); }
+ void bar(int x) { System.out.println("bar " + x); }
+ }
+
+ aspect HandleLiveness {
+ before(Handle handle): target(handle) && call(public * *(..)) {
+ if ( handle.partner == null || !handle.partner.isAlive() ) {
+ throw new DeadPartnerException();
+ }
+ }
+ }
+
+ class DeadPartnerException extends RuntimeException {}
+]]></programlisting>
+
+ </sect2>
+
+ </sect1>
+
+ <sect1>
+ <title>Advice</title>
+
+ <para>
+ Advice defines pieces of aspect implementation that execute at
+ well-defined points in the execution of the program. Those points can be
+ given either by named pointcuts (like the ones you've seen above) or by
+ anonymous pointcuts. Here is an example of an advice on a named pointcut:
+ </para>
+
+<programlisting><![CDATA[
+ pointcut setter(Point p1, int newval): target(p1) && args(newval)
+ (call(void setX(int) ||
+ call(void setY(int)));
+
+ before(Point p1, int newval): setter(p1, newval) {
+ System.out.println("About to set something in " + p1 +
+ " to the new value " + newval);
+ }
+]]></programlisting>
+
+ <para>
+ And here is exactly the same example, but using an anonymous
+ pointcut:
+ </para>
+
+<programlisting><![CDATA[
+ before(Point p1, int newval): target(p1) && args(newval)
+ (call(void setX(int)) ||
+ call(void setY(int))) {
+ System.out.println("About to set something in " + p1 +
+ " to the new value " + newval);
+ }
+]]></programlisting>
+
+ <para>
+ Here are examples of the different advice:
+ </para>
+
+<programlisting><![CDATA[
+ before(Point p, int x): target(p) && args(x) && call(void setX(int)) {
+ if (!p.assertX(x)) return;
+ }
+]]></programlisting>
+
+ <para>
+ This before advice runs just before the execution of the actions
+ associated with the events in the (anonymous) pointcut.
+ </para>
+
+<programlisting><![CDATA[
+ after(Point p, int x): target(p) && args(x) && call(void setX(int)) {
+ if (!p.assertX(x)) throw new PostConditionViolation();
+ }
+]]></programlisting>
+
+ <para>
+ This after advice runs just after each join point picked out by the
+ (anonymous) pointcut, regardless of whether it returns normally or throws
+ an exception.
+ </para>
+
+<programlisting><![CDATA[
+ after(Point p) returning(int x): target(p) && call(int getX()) {
+ System.out.println("Returning int value " + x + " for p = " + p);
+ }
+]]></programlisting>
+
+ <para>
+ This after returning advice runs just after each join point picked out by
+ the (anonymous) pointcut, but only if it returns normally. The return
+ value can be accessed, and is named <literal>x</literal> here. After the
+ advice runs, the return value is returned.
+ </para>
+
+<programlisting><![CDATA[
+ after() throwing(Exception e): target(Point) && call(void setX(int)) {
+ System.out.println(e);
+ }
+]]></programlisting>
+
+ <para>
+ This after throwing advice runs just after each join point picked out by
+ the (anonymous) pointcut, but only when it throws an exception of type
+ <literal>Exception</literal>. Here the exception value can be accessed
+ with the name <literal>e</literal>. The advice re-raises the exception
+ after it's done.
+ </para>
+
+<programlisting><![CDATA[
+void around(Point p, int x): target(p)
+ && args(x)
+ && call(void setX(int)) {
+ if (p.assertX(x)) proceed(p, x);
+ p.releaseResources();
+}
+]]></programlisting>
+
+ <para>
+ This around advice traps the execution of the join point; it runs
+ <emphasis>instead</emphasis> of the join point. The original action
+ associated with the join point can be invoked through the special
+ <literal>proceed</literal> call.
+ </para>
+
+ </sect1>
+
+ <sect1>
+ <title>Introduction</title>
+
+ <para>
+ Introduction declarations add whole new elements in the given types, and
+ so change the type hierarchy. Here are examples of introduction
+ declarations:
+ </para>
+
+<programlisting><![CDATA[
+ private boolean Server.disabled = false;
+]]></programlisting>
+
+ <para>
+ This privately introduces a field named <literal>disabled</literal> in
+ <literal>Server</literal> and initializes it to
+ <literal>false</literal>. Because it is declared
+ <literal>private</literal>, only code defined in the aspect can access
+ the field.
+ </para>
+
+<programlisting><![CDATA[
+ public int Point.getX() { return x; }
+]]></programlisting>
+
+ <para>
+ This publicly introduces a method named <literal>getX</literal> in
+ <literal>Point</literal>; the method returns an <literal>int</literal>,
+ it has no arguments, and its body is return <literal>x</literal>.
+ Because it is defined publically, any code can call it.
+ </para>
+
+<programlisting><![CDATA[
+ public Point.new(int x, int y) { this.x = x; this.y = y; }
+]]></programlisting>
+
+ <para>
+ This publicly introduces a constructor in Point; the constructor has
+ two arguments of type int, and its body is this.x = x; this.y = y;
+ </para>
+
+<programlisting><![CDATA[
+ public int Point.x = 0;
+]]></programlisting>
+
+ <para>
+ This publicly introduces a field named x of type int in Point; the
+ field is initialized to 0.
+ </para>
+
+<programlisting><![CDATA[
+ declare parents: Point implements Comparable;
+]]></programlisting>
+
+ <para>
+ This declares that the <literal>Point</literal> class now implements the
+ <literal>Comparable</literal> interface. Of course, this will be an error
+ unless <literal>Point</literal> defines the methods of
+ <literal>Comparable</literal>.
+ </para>
+
+<programlisting><![CDATA[
+ declare parents: Point extends GeometricObject;
+]]></programlisting>
+
+ <para>
+ This declares that the <literal>Point</literal> class now extends the
+ <literal>GeometricObject</literal> class.
+ </para>
+
+ <para>
+ An aspect can introduce several elements in at the same time. For
+ example, the following declaration
+ </para>
+
+<programlisting><![CDATA[
+ public String Point.name;
+ public void Point.setName(String name) { this.name = name; }
+]]></programlisting>
+
+ <para>
+ publicly introduces both a field and a method into class
+ <literal>Point</literal>. Note that the identifier "name" in the body of
+ the method is bound to the "name" field in <literal>Point</literal>, even
+ if the aspect defined another field called "name".
+ </para>
+
+ <para>
+ One declaration can introduce several elements in several classes as
+ well. For example,
+ </para>
+
+<programlisting><![CDATA[
+ public String (Point || Line || Square).getName() { return name; }
+]]></programlisting>
+
+ <para>
+ publicly introduces three methods, one in <literal>Point</literal>,
+ another in Line and another in <literal>Square</literal>. The three
+ methods have the same name (getName), no parameters, return a String, and
+ have the same body (return name;). The purpose of introducing several
+ elements in one single declaration is that their bodies are the same. The
+ introduction is an error if any of <literal>Point</literal>,
+ <literal>Line</literal>, or <literal>Square</literal> do not have a
+ "name" field.
+ </para>
+
+ <para>
+ An aspect can introduce fields and methods (even with bodies) onto
+ interfaces as well as classes.
+ </para>
+
+ <sect2>
+ <title>Introduction Scope</title>
+
+ <para>
+ AspectJ allows private and package-protected (default) introduction in
+ addition to public introduction. Private introduction means private in
+ relation to the aspect, not necessarily the target type. So, if an
+ aspect makes a private introduction of a field on a type
+ </para>
+
+<programlisting><![CDATA[
+ private int Foo.x;
+]]></programlisting>
+
+ <para>
+ Then code in the aspect can refer to Foo's x field, but nobody else
+ can. Similarly, if an aspect makes a package-protected
+ introduction,
+ </para>
+
+<programlisting><![CDATA[
+ int Foo.x;
+]]></programlisting>
+
+ <para>
+ then everything in the aspect's package (which may not be Foo's
+ package) can access x.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Example: <literal>PointAssertions</literal></title>
+ <para>
+ The example below consists of one class and one aspect. The aspect
+ introduces all implementation that is related with assertions of the
+ class. It privately introduces two methods in the class Point, namely
+ assertX and assertY. It also advises the two set methods of Point with
+ before declarations that assert the validity of the given values. The
+ introductions are made privately because other parts of the program
+ have no business accessing the assert methods. Only the code inside of
+ the aspect can call those methods.
+ </para>
+
+<programlisting><![CDATA[
+ class Point {
+ int x, y;
+
+ public void setX(int x) { this.x = x; }
+ public void setY(int y) { this.y = y; }
+
+ public static void main(String[] args) {
+ Point p = new Point();
+ p.setX(3); p.setY(333);
+ }
+ }
+
+ aspect PointAssertions {
+
+ private boolean Point.assertX(int x) {
+ return (x <= 100 && x >= 0);
+ }
+ private boolean Point.assertY(int y) {
+ return (y <= 100 && y >= 0);
+ }
+
+ before(Point p, int x): target(p) && args(x) && call(void setX(int)) {
+ if (!p.assertX(x)) {
+ System.out.println("Illegal value for x"); return;
+ }
+ }
+ before(Point p, int y): target(p) && args(y) && call(void setY(int)) {
+ if (!p.assertY(y)) {
+ System.out.println("Illegal value for y"); return;
+ }
+ }
+ }
+]]></programlisting>
+
+ </sect2>
+ </sect1>
+
+<!-- ================================================== -->
+
+ <sect1>
+ <title>Reflection</title>
+
+ <para>
+ AspectJ provides a special reference variable, thisJoinPoint, that
+ contains reflective information about the current join point for the
+ advice to use. The thisJoinPoint variable can only be used in the context
+ of advice, just like this can only be used in the context of non-static
+ methods and variable initializers. In advice, thisJoinPoint is an object
+ of type JoinPoint.
+ </para>
+
+ <para>
+ One way to use it is simply to print it out. Like all Java objects,
+ thisJoinPoint has a toString() method that makes quick-and-dirty tracing
+ easy.
+ </para>
+
+<programlisting><![CDATA[
+ class TraceNonStaticMethods {
+ before(Point p): target(p) && call(* *(..)) {
+ System.out.println("Entering " + thisJoinPoint + " in " + p);
+ }
+ }
+]]></programlisting>
+
+ <para>
+ The type of thisJoinPoint includes a rich reflective class hierarchy of
+ signatures, and can be used to access both static and dynamic information
+ about join points. If, however, only the static information about the
+ join point (such as the Signature) is desired, a lightweight join-point
+ object is available from the thisJoinPointStaticPart special variable.
+ This object is the same object you would get from
+ </para>
+
+
+<programlisting><![CDATA[
+ thisJoinPoint.getStaticPart()
+]]></programlisting>
+
+ <para>
+ The static part of a join point does not include dynamic information,
+ such as the arguments, which can be accessed with
+ </para>
+
+<programlisting><![CDATA[
+ thisJoinPoint.getArgs()
+]]></programlisting>
+
+ <para>
+ But it has the performance benefit that repeated execution of the code
+ containing <literal>thisJoinPointStaticPart</literal> (through, for
+ example, separate method calls) will not result in repeated construction
+ of the reflective object.
+ </para>
+
+ <para>It is always the case that
+ </para>
+
+<programlisting><![CDATA[
+ thisJoinPointStaticPart == thisJoinPoint.getStaticPart()
+
+ thisJoinPoint.getKind() == thisJoinPointStaticPart.getKind()
+ thisJoinPoint.getSignature() == thisJoinPointStaticPart.getSignature()
+ thisJoinPoint.getSourceLocation() == thisJoinPointStaticPart.getSourceLocation()
+]]></programlisting>
+
+ <para>
+ One more reflective variable is available:
+ <literal>thisEnclosingJoinPointStaticPart</literal>. This, like
+ <literal>thisJoinPointStaticPart</literal>, only holds the static part of
+ a join point, but it is not the current but the enclosing join point.
+ So, for example, it is possible to print out the calling source location
+ (if available) with
+ </para>
+
+
+<programlisting><![CDATA[
+ before() : execution (* *(..)) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getSourceLocation())
+ }
+]]></programlisting>
+
+ </sect1>
+
+</chapter>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- compile-command: "ant -quiet prog-html" -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.xml" "book" "chapter") -->
+<!-- End: -->
diff --git a/docs/progGuideDB/limitations.xml b/docs/progGuideDB/limitations.xml
new file mode 100644
index 000000000..41e10db45
--- /dev/null
+++ b/docs/progGuideDB/limitations.xml
@@ -0,0 +1,123 @@
+<appendix id="limitations" xreflabel="Implementation Limitations">
+
+ <title>Implementation Limitations</title>
+
+ <para>
+ Certain elements of AspectJ's semantics are difficult to implement without
+ making modifications to the virtual machine. One way to deal with this
+ problem would be to specify only the behavior that is easiest to implement.
+ We have chosen a somewhat different approach, which is to specify an ideal
+ language semantics, as well as a clearly defined way in which
+ implementations are allowed to deviate from that semantics. This makes it
+ possible to develop conforming AspectJ implementations today, while still
+ making it clear what later, and presumably better, implementations should do
+ tomorrow.
+ </para>
+
+ <para>
+ According to the AspectJ language semantics, the declaration
+ </para>
+
+<programlisting><![CDATA[
+before(): get(int Point.x) { System.out.println("got x"); }
+]]></programlisting>
+
+ <para>
+ should advise all accesses of a field of type int and name x from instances
+ of type (or subtype of) Point. It should do this regardless of whether all
+ the source code performing the access was available at the time the aspect
+ containing this advice was compiled, whether changes were made later, etc.
+ </para>
+
+ <para>
+ But AspectJ implementations are permitted to deviate from this in a
+ well-defined way -- they are permitted to advise only accesses in
+ <emphasis>code the implementation controls</emphasis>. Each implementation
+ is free within certain bounds to provide its own definition of what it means
+ to control code.
+ </para>
+
+ <para>
+ In the current AspectJ compiler, ajc, control of the code means having
+ source code for any aspects and all the code they should affect available
+ during the compile. This means that if some class Client contains code with
+ the expression <literal>new Point().x</literal> (which results in a field
+ get join point at runtime), the current AspectJ compiler will fail to advise
+ that access unless Client.java is compiled at the same the aspect is
+ compiled. It also means that join points associated with code in precompiled
+ libraries (such as java.lang), and join points associated with code in
+ native methods (including their execution join points), can not be advised.
+ </para>
+
+ <para>
+ Different join points have different requirements. Method call join points
+ can be advised only if ajc controls <emphasis>either</emphasis> the code for
+ the caller or the code for the receiver, and some call pointcut designators
+ may require caller context (what the static type of the receiver is, for
+ example) to pick out join points. Constructor call join points can be
+ advised only if ajc controls the code for the caller. Field reference or
+ assignment join points can be advised only if ajc controls the code for the
+ "caller", the code actually making the reference or assignment.
+ Initialization join points can be advised only if ajc controls the code of
+ the type being initialized, and execution join points can be advised only if
+ ajc controls the code for the method or constructor body in question.
+ </para>
+
+ <para>
+ Aspects that are defined <literal>perthis</literal> or
+ <literal>pertarget</literal> also have restrictions based on control of the
+ code. In particular, at a join point where the source code for the
+ currently executing object is not available, an aspect defined
+ <literal>perthis</literal> of that join point will not be associated. So
+ aspects defined <literal>perthis(Object)</literal> will not create aspect
+ instances for every object, just those whose class the compiler controls.
+ Similar restrictions apply to <literal>pertarget</literal> aspects.
+ </para>
+
+ <para>
+ Inter-type declarations such as <literal>declare parents</literal> also have
+ restrictions based on control of the code. If the code for the target of an
+ inter-type declaration is not available, then the inter-type declaration is
+ not made on that target. So, <literal>declare parents : String implements
+ MyInterface</literal> will not work for
+ <literal>java.lang.String</literal>.
+ </para>
+
+ <para>
+ Other AspectJ implementations, indeed, future versions of ajc, may define
+ <emphasis>code the implementation controls</emphasis> more liberally.
+ </para>
+
+ <para>
+ Control may mean that classes need only be available in classfile or jarfile
+ format. So, even if Client.java and Point.java were precompiled, their join
+ points could still be advised. In such a system, though, it might still be
+ the case that join points from code of system libraries such as java.lang
+ could not be advised.
+ </para>
+
+ <para>
+ Or control could even include system libraries, thus allowing a call join
+ point from java.util.Hashmap to java.lang.Object to be advised.
+ </para>
+
+ <para>
+ All AspectJ implementations are required to control the code of the
+ files that the compiler compiles itself.
+ </para>
+
+ <para>
+ The important thing to remember is that core concepts of AspectJ,
+ such as the join point, are unchanged, regardless of which
+ implementation is used. During your development, you will have to
+ be aware of the limitations of the ajc compiler you're using, but
+ these limitations should not drive the design of your aspects.
+ </para>
+
+</appendix>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.sgml" "book" "appendix") -->
+<!-- End: -->
diff --git a/docs/progGuideDB/overview.gif b/docs/progGuideDB/overview.gif
new file mode 100644
index 000000000..7b1d6c8d6
--- /dev/null
+++ b/docs/progGuideDB/overview.gif
Binary files differ
diff --git a/docs/progGuideDB/pitfalls.xml b/docs/progGuideDB/pitfalls.xml
new file mode 100644
index 000000000..5379d5daa
--- /dev/null
+++ b/docs/progGuideDB/pitfalls.xml
@@ -0,0 +1,103 @@
+<chapter id="pitfalls" xreflabel="Pitfalls">
+ <title>Pitfalls</title>
+
+ <sect1><!-- About this Chapter -->
+ <title>About this Chapter</title>
+
+ <para>This chapter consists of aspectj programs that may lead to surprising
+ behaviour and how to understand them.
+ </para>
+
+ </sect1>
+
+ <sect1>
+ <title>Infinite loops</title>
+
+ <para>Here is a Java program with peculiar behavior </para>
+
+<programlisting><![CDATA[
+public class Main {
+ public static void main(String[] args) {
+ foo();
+ System.out.println("done with call to foo");
+ }
+
+ static void foo() {
+ try {
+ foo();
+ } finally {
+ foo();
+ }
+ }
+}
+]]></programlisting>
+
+ <para>This program will never reach the println call, but when it aborts
+ will have no stack trace. </para>
+
+ <para>This silence is caused by multiple StackOverflowExceptions. First
+ the infinite loop in the body of the method generates one, which the
+ finally clause tries to handle. But this finally clause also generates an
+ infinite loop which the current JVMs can't handle gracefully leading to the
+ completely silent abort. </para>
+
+ <para> The following short aspect will also generate this behavior:
+ </para>
+
+<programlisting><![CDATA[
+aspect A {
+ before(): call(* *(..)) { System.out.println("before"); }
+ after(): call(* *(..)) { System.out.println("after"); }
+}
+]]></programlisting>
+
+ <para>Why? Because the call to println is also a call matched by the
+ pointcut <literal>call (* *(..))</literal>. We get no output because we
+ used simple after() advice. If the aspect were changed to</para>
+
+<programlisting><![CDATA[
+aspect A {
+ before(): call(* *(..)) { System.out.println("before"); }
+ after() returning: call(* *(..)) { System.out.println("after"); }
+}
+]]></programlisting>
+
+ <para>Then at least a StackOverflowException with a stack trace would be
+ seen. In both cases, though, the overall problem is advice applying within
+ its own body. </para>
+
+ <para>There's a simple idiom to use if you ever have a worry that your
+ advice might apply in this way. Just restrict the advice from occurring in
+ join points caused within the aspect. So: </para>
+
+<programlisting><![CDATA[
+aspect A {
+ before(): call(* *(..)) && !within(A) { System.out.println("before"); }
+ after() returning: call(* *(..)) && !within(A) { System.out.println("after"); }
+}
+]]></programlisting>
+
+ <para>Other solutions might be to more closely restrict the pointcut in
+ other ways, for example: </para>
+
+<programlisting><![CDATA[
+aspect A {
+ before(): call(* MyObject.*(..)) { System.out.println("before"); }
+ after() returning: call(* MyObject.*(..)) { System.out.println("after"); }
+}
+]]></programlisting>
+
+ <para>The moral of the story is that unrestricted generic pointcuts can
+ pick out more join points than intended. </para>
+
+ </sect1>
+</chapter>
+
+<!--
+Local variables:
+compile-command: "java sax.SAXCount -v progguide.xml && java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl"
+fill-column: 79
+sgml-local-ecat-files: "progguide.ced"
+sgml-parent-document:("progguide.xml" "book" "chapter")
+End:
+-->
diff --git a/docs/progGuideDB/preface.xml b/docs/progGuideDB/preface.xml
new file mode 100644
index 000000000..4f5575fcf
--- /dev/null
+++ b/docs/progGuideDB/preface.xml
@@ -0,0 +1,52 @@
+<preface>
+ <title>Preface</title>
+
+ <para>
+ This user's guide does three things. It
+ <itemizedlist spacing="compact">
+ <listitem>
+ <para>introduces the AspectJ language</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ defines each of AspectJ's constructs and their semantics, and</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ provides examples of their use.</para>
+ </listitem>
+ </itemizedlist>
+ Three appendices give a quick reference, a more formal definition of
+ AspectJ, and a glossary.
+ </para>
+
+ <para>The first section, <xref linkend="gettingstarted" />, provides a gentle
+ overview of writing AspectJ programs. It also shows how one can introduce
+ AspectJ into an existing development effort in stages, reducing the
+ associated risk. You should read this section if this is your first
+ exposure to AspectJ and you want to get a sense of what AspectJ is all
+ about.</para>
+
+ <para>The second section, <xref linkend="aspectjlanguage" />, covers the
+ features of the language in more detail, using code snippets as examples.
+ The entire language is covered, and after reading this section, you should
+ be able to use all the features of the language correctly.</para>
+
+ <para>The next section, <xref linkend="examples" />, comprises a set of
+ complete programs that not only show the features being used, but also try
+ to illustrate recommended practice. You should read this section after you
+ are familiar with the elements of AspectJ.</para>
+
+ <para>The back matter contains several appendices that cover AspectJ's
+ semantics, a quick reference to the language, a glossary of terms and the
+ index.</para>
+
+</preface>
+
+<!-- Local variables: -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.sgml" "book" "preface") -->
+<!-- End: -->
+
diff --git a/docs/progGuideDB/progguide.html.xsl b/docs/progGuideDB/progguide.html.xsl
new file mode 100644
index 000000000..4683e404f
--- /dev/null
+++ b/docs/progGuideDB/progguide.html.xsl
@@ -0,0 +1,9 @@
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:import href="../../../aspectj-external-lib/docbook/docbook-xsl/html/chunk.xsl"/>
+
+<xsl:param name="base.dir" select="'html/'"/>
+<xsl:param name="html.ext" select="'.html'"/>
+
+</xsl:stylesheet>
diff --git a/docs/progGuideDB/progguide.xml b/docs/progGuideDB/progguide.xml
new file mode 100644
index 000000000..0128b3490
--- /dev/null
+++ b/docs/progGuideDB/progguide.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "../../lib/docbook/docbook-dtd/docbookx.dtd"
+[
+
+<!ENTITY preface SYSTEM "preface.xml">
+<!ENTITY gettingstarted SYSTEM "gettingstarted.xml">
+<!ENTITY language SYSTEM "language.xml">
+<!ENTITY examples SYSTEM "examples.xml">
+<!ENTITY idioms SYSTEM "idioms.xml">
+<!ENTITY pitfalls SYSTEM "pitfalls.xml">
+<!ENTITY quickreference SYSTEM "quickreference.xml">
+<!ENTITY semantics SYSTEM "semantics.xml">
+<!ENTITY limitations SYSTEM "limitations.xml">
+<!ENTITY glossary SYSTEM "glossary.xml">
+<!ENTITY bibliography SYSTEM "bibliography.xml">
+<!ENTITY index SYSTEM "index.xml">
+
+<!ENTITY % early "ignore">
+
+]>
+
+<book>
+ <bookinfo>
+ <title>The AspectJ<superscript>TM</superscript> Programming Guide</title>
+
+ <authorgroup>
+ <author>
+ <othername>the AspectJ Team</othername>
+ </author>
+ </authorgroup>
+
+ <legalnotice>
+ <para>Copyright (c) 1998-2001 Xerox Corporation,
+ 2002 Palo Alto Research Center, Incorporated.
+ All rights reserved.
+ </para>
+ </legalnotice>
+
+ <abstract>
+ <para>
+ This programming guide describes the AspectJ language. A
+ companion guide describes the tools which are part of the
+ AspectJ development environment.
+ </para>
+
+ <para>
+ If you are completely new to AspectJ, you should first read
+ <xref linkend="gettingstarted"/> for a broad overview of programming
+ in AspectJ. If you are already familiar with AspectJ, but want a deeper
+ understanding, you should read <xref linkend="aspectjlanguage"/> and
+ look at the examples in the chapter. If you want a more formal
+ definition of AspectJ, you should read <xref linkend="semantics"/>.
+ </para>
+ </abstract>
+ </bookinfo>
+
+ &preface;
+ &gettingstarted;
+ &language;
+ &examples;
+ &idioms;
+ &pitfalls;
+ &quickreference;
+ &semantics;
+ &limitations;
+ &glossary;
+ &bibliography;
+<!-- &index; -->
+
+
+
+</book>
+
+<!--
+Local Variables:
+compile-command: "java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl"
+fill-column: 79
+sgml-indent-step: 3
+sgml-local-ecat-files: "progguide.ced"
+End:
+-->
diff --git a/docs/progGuideDB/quickreference.xml b/docs/progGuideDB/quickreference.xml
new file mode 100644
index 000000000..2b0c98f14
--- /dev/null
+++ b/docs/progGuideDB/quickreference.xml
@@ -0,0 +1,658 @@
+<appendix id="quickreference" xreflabel="AspectJ Quick Reference">
+
+ <title>AspectJ Quick Reference</title>
+ <indexterm><primary>AspectJ</primary><secondary>semantics</secondary>
+ <tertiary>quick reference</tertiary>
+ </indexterm>
+
+ <sect1>
+ <title>Pointcut Designators</title>
+
+ <table frame="all" id="qrpointcutdesignators">
+ <title>Pointcut Designators</title>
+
+ <tgroup cols="2" align="left">
+ <colspec colname="c1"/>
+ <colspec colname="c2"/>
+ <spanspec spanname="hspan" namest="c1" nameend="c2" align="left"/>
+
+ <tbody valign="middle">
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Methods and Constructors</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>call(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Method or constructor call join points when the signature
+ matches <replaceable>Signature</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>execution(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Method or constructor execution join points when the
+ signature matches
+ <replaceable>Signature</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>initialization(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Object initialization join point when the first
+ constructor called in the type matches
+ <replaceable>Signature</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Exception Handlers</emphasis>
+ </entry>
+ </row>
+
+ <row rowsep="1">
+ <entry>
+ <literal>handler(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Exception handler execution join points when
+ try handlers for the throwable types in
+ <replaceable>TypePattern</replaceable> are executed.
+ The exception object can be accessed with an
+ <literal>args</literal> pointcut.
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Fields</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>get(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Field reference join points when the field matches
+ <replaceable>Signature</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>set(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Field assignment join points when the field matches
+ <replaceable>Signature</replaceable>. The new value
+ can be accessed with an <literal>args</literal>
+ pointcut.
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Static Initializers</emphasis>
+ </entry>
+ </row>
+
+ <row rowsep="1">
+ <entry>
+ <literal>staticinitialization(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Static initializer execution join points for the types in
+ <replaceable>TypePattern</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Objects</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>this(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points when the currently executing object is an
+ instance of a type in <replaceable>TypePattern</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>target(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points when the target object is an instance
+ of a type in <replaceable>TypePattern</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>args(<replaceable>TypePattern</replaceable>, ...)</literal>
+ </entry>
+ <entry>
+ Join points when the argument objects are instances of
+ the <replaceable>TypePattern</replaceable>s
+ </entry>
+ </row>
+
+<!--
+ <row rowsep="1">
+ <entry>
+ <literal>hasaspect(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points where an aspect instance of a type in
+ <replaceable>TypePattern</replaceable> is associated
+ with the join point
+ </entry>
+ </row>
+-->
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Lexical Extents</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>within(<replaceable>TypePattern</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points when the code executing is defined in the
+ types in <replaceable>TypePattern</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>withincode(<replaceable>Signature</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points when the code executing is defined in the
+ method or constructor with signature
+ <replaceable>Signature</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Control Flow</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>cflow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points in the control flow of the join points
+ specified by <replaceable>Pointcut</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>cflowbelow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points in the control flow below the join points
+ specified by <replaceable>Pointcut</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Conditional</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>if(<replaceable>Expression</replaceable>)</literal>
+ </entry>
+ <entry>
+ Join points when the boolean
+ <replaceable>Expression</replaceable> evaluates
+ to <literal>true</literal>
+ </entry>
+ </row>
+
+ <row>
+ <entry spanname="hspan">
+ <emphasis role="bold">Combination</emphasis>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>! <replaceable>Pointcut</replaceable></literal>
+ </entry>
+ <entry>
+ Join points that are not picked out by
+ <replaceable>Pointcut</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><replaceable>Pointcut0</replaceable> <![CDATA[&&]]> <replaceable>Pointcut1</replaceable></literal>
+ </entry>
+ <entry>
+ Join points that are picked out by both
+ <replaceable>Pointcut0</replaceable> and
+ <replaceable>Pointcut1</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><replaceable>Pointcut0</replaceable> || <replaceable>Pointcut1</replaceable></literal>
+ </entry>
+ <entry>
+ Join points that are picked out by either
+ <replaceable>Pointcut0</replaceable> or
+ <replaceable>Pointcut1</replaceable>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>( <replaceable>Pointcut</replaceable> )</literal>
+ </entry>
+ <entry>
+ Join points that are picked out by the parenthesized
+ <replaceable>Pointcut</replaceable>
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+
+ </table>
+
+ </sect1>
+
+ <sect1>
+ <title>Type Patterns</title>
+ <para>
+ </para>
+
+ <table frame="all" id="qrtypenamepatterns">
+ <title>Type Name Patterns</title>
+ <tgroup cols="2" colsep="1" rowsep="0">
+ <tbody>
+ <row>
+ <entry><literal>*</literal> alone</entry>
+ <entry>all types</entry>
+ </row>
+ <row>
+ <entry><literal>*</literal> in an identifier</entry>
+ <entry>any sequence of characters, not including "."</entry>
+ </row>
+ <row>
+ <entry><literal>..</literal> in an identifier</entry>
+ <entry>any sequence of characters starting and ending
+ with "."</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The + wildcard can be appended to a type name pattern to
+ indicate all subtypes.
+ </para>
+
+ <para>
+ Any number of []s can be put on a type name or subtype pattern
+ to indicate array types.
+ </para>
+
+ <table frame="all" id="qrtypepatterns">
+ <title>Type Patterns</title>
+ <tgroup cols="2" colsep="1" rowsep="0">
+ <tbody>
+ <row>
+ <entry><replaceable>TypeNamePattern</replaceable></entry>
+ <entry>all types in <replaceable>TypeNamePattern</replaceable></entry>
+ </row>
+ <row>
+ <entry><replaceable>SubtypePattern</replaceable></entry>
+ <entry>all types in <replaceable>SubtypePattern</replaceable>, a
+ pattern with a +. </entry>
+ </row>
+ <row>
+ <entry><replaceable>ArrayTypePattern</replaceable></entry>
+ <entry>all types in <replaceable>ArrayTypePattern</replaceable>,
+ a pattern with one or more []s. </entry>
+ </row>
+ <row>
+ <entry><literal>!<replaceable>TypePattern</replaceable></literal></entry>
+ <entry>all types not in <replaceable>TypePattern</replaceable></entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>TypePattern0</replaceable>
+ <![CDATA[&&]]> <replaceable>TypePattern1</replaceable></literal></entry>
+ <entry>all types in both
+ <replaceable>TypePattern0</replaceable> and <replaceable>TypePattern1</replaceable></entry>
+ </row>
+ <row>
+ <entry><literal><replaceable>TypePattern0</replaceable> || <replaceable>TypePattern1</replaceable></literal></entry>
+ <entry>all types in either
+ <replaceable>TypePattern0</replaceable> or <replaceable>TypePattern1</replaceable></entry>
+ </row>
+ <row>
+ <entry><literal>( <replaceable>TypePattern</replaceable> )</literal></entry>
+ <entry>all types in <replaceable>TypePattern</replaceable></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1>
+ <title>Advice</title>
+
+ <para></para>
+ <table frame="all" id="qradvice">
+ <title>Advice</title>
+ <tgroup cols="2" colsep="1" rowsep="0">
+ <tbody>
+
+ <row>
+ <entry>
+ <literal>before(<replaceable>Formals</replaceable>) : </literal>
+ </entry>
+ <entry>
+ Run before the join point.
+ </entry>
+ </row>
+
+
+ <row>
+ <entry>
+ <literal>after(<replaceable>Formals</replaceable>) returning
+ [ (<replaceable>Formal</replaceable>) ] : </literal>
+ </entry>
+ <entry>
+ Run after the join point if it returns normally. The
+ optional formal gives access to the returned value.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>after(<replaceable>Formals</replaceable>) throwing [
+ (<replaceable>Formal</replaceable>) ] : </literal>
+ </entry>
+ <entry>
+ Run after the join point if it throws an exception. The
+ optional formal gives access to the
+ <literal>Throwable</literal> exception value.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>after(<replaceable>Formals</replaceable>) : </literal>
+ </entry>
+ <entry>
+ Run after the join point both when it returns normally and
+ when it throws an exception.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><replaceable>Type</replaceable>
+ around(<replaceable>Formals</replaceable>) [ throws
+ <replaceable>TypeList</replaceable> ] :</literal>
+ </entry>
+ <entry>
+ Run instead of the join point. The join point can be
+ executed by calling <literal>proceed</literal>.
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1>
+ <title>Static Crosscutting</title>
+
+ <para></para>
+
+ <table frame="all" id="qrintroduction">
+ <title>Introduction</title>
+
+ <tgroup cols="2" colsep="1" rowsep="0">
+
+ <tbody>
+
+ <row>
+ <entry>
+ <replaceable>Modifiers Type TypePattern.Id(Formals) { Body }</replaceable>
+ </entry>
+ <entry>
+ Defines a method on the types in <replaceable>TypePattern</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>abstract <replaceable>Modifiers Type TypePattern.Id(Formals)</replaceable>;</literal>
+ </entry>
+ <entry>
+ Defines an abstract method on the types in <replaceable>TypePattern</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal><replaceable>Modifiers TypePattern</replaceable>.new<replaceable>(Formals) { Body }</replaceable></literal>
+ </entry>
+ <entry>
+ Defines a a constructor on the types in <replaceable>TypePattern</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <replaceable>Modifiers Type TypePattern.Id [ = Expression ];</replaceable>
+ </entry>
+ <entry>
+ Defines a field on the types in <replaceable>TypePattern</replaceable>.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <table frame="all" id="qrotherdeclarations">
+ <title>Other declarations</title>
+
+ <tgroup cols="2" colsep="1" rowsep="0">
+
+ <tbody>
+
+ <row>
+ <entry>
+ <literal>declare parents: <replaceable>TypePattern</replaceable> extends <replaceable>TypeList</replaceable>;</literal>
+ </entry>
+ <entry>
+ Declares that the types in <replaceable>TypePattern</replaceable> extend the types of <replaceable>TypeList</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>declare parents: <replaceable>TypePattern</replaceable> implements <replaceable>TypeList</replaceable>;</literal>
+ </entry>
+ <entry>
+ Declares that the types in <replaceable>TypePattern</replaceable> implement the types of <replaceable>TypeList</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>declare warning: <replaceable>Pointcut</replaceable>: <replaceable>String</replaceable>;</literal>
+ </entry>
+ <entry>
+ Declares that if any of the join points in
+ <replaceable>Pointcut</replaceable> possibly exist in
+ the program, the compiler should emit a warning of
+ <replaceable>String</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>declare error: <replaceable>Pointcut</replaceable>: <replaceable>String</replaceable>;</literal>
+ </entry>
+ <entry>
+ Declares that if any of the join points in
+ <replaceable>Pointcut</replaceable> possibly exist in
+ the program, the compiler should emit an error of
+ <replaceable>String</replaceable>.
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>declare soft:
+ <replaceable>TypePattern</replaceable>:
+ <replaceable>Pointcut</replaceable>; </literal>
+ </entry>
+ <entry>
+ Declares that any exception of a type in
+ <replaceable>TypePattern</replaceable> that gets
+ thrown at any join point picked out by
+ <replaceable>Pointcut</replaceable> will be wrapped in
+ <literal>org.aspectj.lang.SoftException</literal>.
+ </entry>
+ </row>
+
+ </tbody>
+ </tgroup>
+ </table>
+
+ </sect1>
+
+ <sect1>
+ <title>Aspect Associations</title>
+ <para>
+ </para>
+
+ <table frame="all" id="qrassociations">
+ <title>Associations</title>
+ <tgroup cols="3" align="left" colsep="1" rowsep="1">
+ <thead>
+ <row>
+ <entry>modifier</entry>
+ <entry>Description</entry>
+ <entry>Accessor</entry>
+ </row>
+ </thead>
+
+ <tbody>
+
+ <row>
+ <entry>
+ [ <literal>issingleton</literal> ]
+ </entry>
+ <entry>
+ One instance of the aspect is made. This is
+ the default.
+ </entry>
+ <entry>
+ <literal>aspectOf()</literal> at all join points
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>perthis(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ An instance is associated with each object that is the
+ currently executing object at any join point in
+ <replaceable>Pointcut</replaceable>.
+ </entry>
+ <entry>
+ <literal>aspectOf(Object)</literal> at all join points</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>pertarget(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ An instance is associated with each object that is the
+ target object at any join point in
+ <replaceable>Pointcut</replaceable>.
+ </entry>
+ <entry>
+ <literal>aspectOf(Object)</literal> at all join points</entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>percflow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ The aspect is defined for each entrance to the control flow of
+ the join points defined by <replaceable>Pointcut</replaceable>. </entry>
+ <entry>
+ <literal>aspectOf()</literal> at join points in
+ <literal>cflow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>percflowbelow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ <entry>
+ The aspect is defined for each entrance to the control flow
+ below the join points defined by <replaceable>Pointcut</replaceable>.
+ </entry>
+ <entry>
+ <literal>aspectOf()</literal> at join points in
+ <literal>cflowbelow(<replaceable>Pointcut</replaceable>)</literal>
+ </entry>
+ </row>
+ </tbody>
+
+ </tgroup>
+ </table>
+ </sect1>
+</appendix>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: progguide.ced -->
+<!-- sgml-parent-document:("progguide.sgml" "book" "appendix") -->
+<!-- End: -->
diff --git a/docs/progGuideDB/semantics.xml b/docs/progGuideDB/semantics.xml
new file mode 100644
index 000000000..cf77a23ed
--- /dev/null
+++ b/docs/progGuideDB/semantics.xml
@@ -0,0 +1,2361 @@
+<appendix id="semantics" xreflabel="Semantics">
+
+ <title>Language Semantics</title>
+
+ <para>
+ AspectJ extends Java by overlaying a concept of join points onto the
+ existing Java semantics and by adding adds four kinds of program elements
+ to Java:
+ </para>
+
+ <para>
+ Join points are well-defined points in the execution of a program. These
+ include method and constructor calls, field accesses and others described
+ below.
+ </para>
+
+ <para>
+ A pointcut picks out join points, and exposes some of the values in the
+ execution context of those join points. There are several primitive
+ pointcut designators, new named pointcuts can be defined by the
+ <literal>pointcut</literal> declaration.
+ </para>
+
+ <para>
+ Advice is code that executes at each join point in a pointcut. Advice has
+ access to the values exposed by the pointcut. Advice is defined by
+ <literal>before</literal>, <literal>after</literal>, and
+ <literal>around</literal> declarations.
+ </para>
+
+ <para>
+ Introduction and declaration form AspectJ's static crosscutting features,
+ that is, is code that may change the type structure of a program, by adding
+ to or extending interfaces and classes with new fields, constructors, or
+ methods. Introductions are defined through an extension of usual method,
+ field, and constructor declarations, and other declarations are made with a
+ new <literal>declare</literal> keyword.
+ </para>
+
+ <para>
+ An aspect is a crosscutting type, that encapsulates pointcuts, advice, and
+ static crosscutting features. By type, we mean Java's notion: a modular
+ unit of code, with a well-defined interface, about which it is possible to
+ do reasoning at compile time. Aspects are defined by the
+ <literal>aspect</literal> declaration.
+ </para>
+
+ <sect1>
+ <title>Join Points</title>
+
+ <para>
+ While aspects do define crosscutting types, the AspectJ system does not
+ allow completely arbitrary crosscutting. Rather, aspects define types that
+ cut across principled points in a program's execution. These principled
+ points are called join points.
+ </para>
+
+
+ <para>
+ A join point is a well-defined point in the execution of a program. The
+ join points defined by AspectJ are:
+ </para>
+
+ <glosslist>
+
+ <glossentry>
+ <glossterm>Method call</glossterm>
+ <glossdef>
+ <para>
+ When a method is called, not including super calls of non-static
+ methods.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Method execution</glossterm>
+ <glossdef>
+ <para>
+ When the body of code for an actual method executes.
+ </para>
+ </glossdef>
+ </glossentry>
+
+
+ <glossentry>
+ <glossterm>Constructor call</glossterm>
+ <glossdef>
+ <para>
+ When an object is built and a constructor is called, not including
+ this or super constructor calls. The object being constructed is
+ returned at a constructor call join point, so it may be accessed
+ with <literal>after returning</literal> advice.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Initializer execution</glossterm>
+ <glossdef>
+ <para>
+ When the non-static initializers of a class run.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Constructor execution</glossterm>
+ <glossdef>
+ <para>
+ When the body of code for an actual constructor executes, after its
+ this or super constructor call. The object being constructed is
+ the currently executing object, and so may be accessed with the
+ <literal>this</literal> pointcut. No value is returned from
+ constructor execution join points.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Static initializer execution</glossterm>
+ <glossdef>
+ <para>
+ When the static initializer for a class executes.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Object pre-initialization</glossterm>
+ <glossdef>
+ <para>
+ Before the object initialization code for a particular class runs.
+ This encompasses the time between the start of its first called
+ constructor and the start of its parent's constructor. Thus, the
+ execution of these join points encompass the join points from the
+ code found in <literal>this()</literal> and
+ <literal>super()</literal> constructor calls.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Object initialization</glossterm>
+ <glossdef>
+ <para>
+ When the object initialization code for a particular class runs.
+ This encompasses the time between the return of its parent's
+ constructor and the return of its first called constructor. It
+ includes all the dynamic initializers and constructors used to
+ create the object. The object being constructed is
+ the currently executing object, and so may be accessed with the
+ <literal>this</literal> pointcut. No value is returned from
+ constructor execution join points.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Field reference</glossterm>
+ <glossdef>
+ <para>
+ When a non-final field is referenced.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Field assignment</glossterm>
+ <glossdef>
+ <para>
+ When a field is assigned to.
+ </para>
+ </glossdef>
+ </glossentry>
+
+ <glossentry>
+ <glossterm>Handler execution</glossterm>
+ <glossdef>
+ <para>
+ When an exception handler executes.
+ </para>
+ </glossdef>
+ </glossentry>
+ </glosslist>
+
+
+
+ </sect1>
+
+ <sect1>
+ <title>Pointcuts</title>
+
+ <para>
+ A pointcut is a program element that picks out join points, as well as
+ data from the execution context of the join points. Pointcuts are used
+ primarily by advice. They can be composed with boolean operators to
+ build up other pointcuts. So a pointcut is defined by one of
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><literal>call(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out a method or constructor call join point based on the
+ static signature at the caller side. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>execution(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out a method or constructor execution join point based on
+ the static signature at the callee side. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>get(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out a field get join point based on the static
+ signature. Note that references to constant fields (static final
+ fields bound to a constant string object or primitive value) are not
+ get join points, since Java requires them to be inlined. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>set(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out a field set join point based on the static
+ signature. Note that the initializations of constant fields (static
+ final fields where the initializer is a constant string object or
+ primitive value) are not set join points, since Java requires their
+ references to be inlined.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>handler(<replaceable>TypePattern</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out an exception handler of any of the Throwable types
+ of the type pattern. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>initialization(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out an object initialization join point based on the
+ static signature of the starting constructor. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>staticinitialization(<replaceable>TypePattern</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out a static initializer execution join point of any of the types
+ of the type pattern. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>within(<replaceable>TypePattern</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the executing code is defined
+ in any of the classes of the type pattern. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>withincode(<replaceable>Signature</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the executing code is defined
+ in the method or constructor of the appropriate signature. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>cflow(<replaceable>Pointcut</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points in the control flow of the join
+ points picked out by the pointcut, including pointcut's join points
+ themselves. </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>cflowbelow(<replaceable>Pointcut</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points in the control flow below the join
+ points picked out by the pointcut. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>this(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the currently executing object
+ (the object bound to <literal>this</literal>) is an instance of a
+ type of the type pattern, or of the type of the identifier.
+ Will not match any join points from static methods.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>target(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the target object (the object
+ on which a call or field operation is applied to) is an instance of a
+ type of the type pattern, or of the type of the
+ identifier. Will not match any calls, gets, or sets to static
+ members. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>args(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>, ...)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the arguments are instances of
+ a type of the appropriate type pattern or identifier. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>PointcutId</replaceable>(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>, ...)</literal></term>
+ <listitem>
+ <para>Picks out all join points that are picked out by the
+ user-defined pointcut designator named by
+ <replaceable>PointcutId</replaceable>. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>if(<replaceable>BooleanExpression</replaceable>)</literal></term>
+ <listitem>
+ <para>Picks out all join points where the boolean expression
+ evaluates to <literal>true</literal>. The boolean expression used
+ can only access static members, variables exposed by teh enclosing
+ pointcut or advice, and <literal>thisJoinPoint</literal> forms. In
+ particular, it cannot call non-static methods on the aspect. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>! <replaceable>Pointcut</replaceable></literal></term>
+ <listitem>
+ <para>Picks out all join points that are not picked out by the
+ pointcut. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>Pointcut0</replaceable> <![CDATA[&&]]> <replaceable>Pointcut1</replaceable></literal></term>
+ <listitem>
+ <para>Picks out all join points that are picked out by both of the
+ pointcuts. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal><replaceable>Pointcut0</replaceable> || <replaceable>Pointcut1</replaceable></literal></term>
+ <listitem>
+ <para>Picks out all join points that are picked out by either of the
+ pointcuts. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>( <replaceable>Pointcut</replaceable> )</literal></term>
+ <listitem>
+ <para>Picks out all join points that are picked out by the
+ parenthesized pointcut. </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <sect2>
+ <title>Pointcut naming
+ </title>
+
+ <para>
+ A named pointcut is defined with the <literal>pointcut</literal>
+ declaration.
+ </para>
+
+
+<programlisting>
+pointcut publicIntCall(int i):
+ call(public * *(int)) <![CDATA[&&]]> args(i);
+</programlisting>
+
+ <para>
+ A named pointcut may be defined in either a class or aspect, and is
+ treated as a member of the class or aspect where it is found. As a
+ member, it may have an access modifier such as
+ <literal>public</literal> or <literal>private</literal>.
+ </para>
+
+<programlisting>
+class C {
+ pointcut publicCall(int i):
+ call(public * *(int)) <![CDATA[&&]]> args(i);
+}
+
+class D {
+ pointcut myPublicCall(int i):
+ C.publicCall(i) <![CDATA[&&]]> within(SomeType);
+}
+</programlisting>
+
+ <para>
+ Pointcuts that are not final may be declared abstract, and defined
+ without a body. Abstract pointcuts may only be declared within
+ abstract aspects.
+ </para>
+
+<programlisting>
+abstract aspect A {
+ abstract pointcut publicCall(int i);
+}
+</programlisting>
+
+ <para>
+ In such a case, an extending aspect may override the abstract
+ pointcut.
+ </para>
+
+<programlisting>
+aspect B extends A {
+ pointcut publicCall(int i): call(public Foo.m(int)) <![CDATA[&&]]> args(i);
+}
+</programlisting>
+
+ <para>For completeness, a pointcut with a declaration may be declared
+ <literal>final</literal>. </para>
+
+ <para>
+ Though named pointcut declarations appear somewhat like method
+ declarations, and can be overridden in subaspects, they cannot be
+ overloaded. It is an error for two pointcuts to be named with the same
+ name in the same class or aspect declaration.
+ </para>
+
+ <para>
+ The scope of a named pointcut is the enclosing class declaration. This
+ is different than the scope of other members; the scope of other
+ members is the enclosing class <emphasis>body</emphasis>. This means
+ that the following code is legal:
+ </para>
+
+<programlisting>
+aspect B percflow(publicCall()) {
+ pointcut publicCall(): call(public Foo.m(int));
+}
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Context exposure</title>
+
+ <para>
+ Pointcuts have an interface; they expose some parts of the execution
+ context of the join points they pick out. For example, the PublicIntCall
+ above exposes the first argument from the receptions of all public
+ unary integer methods. This context is exposed by providing typed
+ formal parameters to named pointcuts and advice, like the formal
+ parameters of a Java method. These formal parameters are bound by name
+ matching.
+ </para>
+
+ <para>
+ On the right-hand side of advice or pointcut declarations, a regular
+ Java identifier is allowed in certain pointcut designators in place of
+ a type or collection of types.
+ There are four primitive pointcut designators where this is allowed:
+ <literal>this</literal>, <literal>target</literal>, and
+ <literal>args</literal><!-- and hasaspect -->. In all such
+ cases, using an identifier rather than a type is as if the type
+ selected was the type of the formal parameter, so that the pointcut
+ </para>
+
+<programlisting>
+pointcut intArg(int i): args(i);
+</programlisting>
+
+ <para>
+ picks out join points where an <literal>int</literal> is being passed
+ as an argument, but furthermore allows advice access to that argument.
+ </para>
+
+ <para>
+ Values can be exposed from named pointcuts as well, so
+ </para>
+
+<programlisting>
+pointcut publicCall(int x): call(public *.*(int)) <![CDATA[&&]]> intArg(x);
+pointcut intArg(int i): args(i);
+</programlisting>
+
+ <para>
+ is a legal way to pick out all calls to public methods accepting an int
+ argument, and exposing that argument.
+ </para>
+
+ <para>
+ There is one special case for this kind of exposure. Exposing an
+ argument of type Object will also match primitive typed arguments, and
+ expose a "boxed" version of the primitive. So,
+ </para>
+
+<programlisting>
+pointcut publicCall(): call(public *.*(..)) <![CDATA[&&]]> args(Object);
+</programlisting>
+
+ <para>
+ will pick out all unary methods that take, as their only argument,
+ subtypes of Object (i.e., not primitive types like
+ <literal>int</literal>), but
+ </para>
+
+<programlisting>
+pointcut publicCall(Object o): call(public *.*(..)) <![CDATA[&&]]> args(o);
+</programlisting>
+
+ <para>
+ will pick out all unary methods that take any argument: And if the
+ argument was an <literal>int</literal>, then the value passed to advice
+ will be of type <literal>java.lang.Integer</literal>.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Primitive pointcuts</title>
+
+ <bridgehead>Method-related pointcuts</bridgehead>
+
+ <para>AspectJ provides two primitive pointcut designators designed to
+ capture method call and execution join points. </para>
+
+ <simplelist>
+ <member><literal>call(<replaceable>Signature</replaceable>)</literal></member>
+ <member><literal>execution(<replaceable>Signature</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>These two pointcuts also pick out constructor call end execution
+ join points. </para>
+
+ <bridgehead>Field-related pointcuts</bridgehead>
+
+ <para>
+ AspectJ provides two primitive pointcut designators designed to
+ capture field reference and assignment join points:
+ </para>
+
+ <simplelist>
+ <member><literal>get(<replaceable>Signature</replaceable>)</literal></member>
+ <member><literal>set(<replaceable>Signature</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>
+ All set join points are treated as having one argument, the value the
+ field is being set to, so at a set join point, that value can be
+ accessed with an <literal>args</literal> pointcut. So an aspect
+ guarding an integer variable x declared in type T might be written as
+ </para>
+
+<programlisting><![CDATA[
+aspect GuardedX {
+ static final int MAX_CHANGE = 100;
+ before(int newval): set(int T.x) && args(newval) {
+ if (Math.abs(newval - T.x) > MAX_CHANGE)
+ throw new RuntimeException();
+ }
+}]]></programlisting>
+
+ <bridgehead>Object creation-related pointcuts</bridgehead>
+
+ <para>
+ AspectJ provides three primitive pointcut designators designed to
+ capture the initializer execution join points of objects.
+ </para>
+
+ <simplelist>
+ <member><literal>call(<replaceable>Signature</replaceable>)</literal></member>
+ <member><literal>initialization(<replaceable>Signature</replaceable>)</literal></member>
+ <member><literal>execution(<replaceable>Signature</replaceable>)</literal></member>
+ </simplelist>
+
+ <bridgehead>Class initialization-related pointcuts</bridgehead>
+
+ <para>
+ AspectJ provides one primitive pointcut designator to pick out
+ static initializer execution join points.
+ </para>
+
+ <simplelist>
+ <member><literal>staticinitialization(<replaceable>TypePattern</replaceable>)</literal></member>
+ </simplelist>
+
+ <bridgehead>Exception handler execution-related pointcuts</bridgehead>
+
+ <para>
+ AspectJ provides one primitive pointcut designator to capture
+ execution of exception handlers:
+ </para>
+
+ <simplelist>
+ <member><literal>handler(<replaceable>TypePattern</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>
+ All handler join points are treated as having one argument, the value
+ of the exception being handled, so at a handler join point, that
+ value can be accessed with an <literal>args</literal> pointcut. So
+ an aspect used to put FooException objects into some normal form
+ before they are handled could be written as
+ </para>
+
+<programlisting>
+aspect NormalizeFooException {
+ before(FooException e): handler(FooException) <![CDATA[&&]]> args(e) {
+ e.normalize();
+ }
+}
+</programlisting>
+
+ <bridgehead>State-based pointcuts</bridgehead>
+
+ <para>
+ Many concerns cut across the dynamic times when an object of a
+ particular type is executing, being operated on, or being passed
+ around. AspectJ provides primitive pointcuts that capture join
+ points at these times. These pointcuts use the dynamic types of
+ their objects to discriminate, or pick out, join points. They may
+ also be used to expose to advice the objects used for
+ discrimination.
+ </para>
+
+ <simplelist>
+ <member><literal>this(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>)</literal></member>
+ <member><literal>target(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>)</literal></member>
+<!-- <member><literal>hasaspect(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable>)</literal></member> -->
+ </simplelist>
+
+ <para>
+ The this pointcut picks out all join points where the currently
+ executing object (the object bound to <literal>this</literal>) is an
+ instance of a particular type. The target pointcut picks out all
+ join points where the target object (the object on which a method is
+ called or a field is accessed) is an instance of a particular type.
+<!-- The hasaspect pointcut picks out all join points where there is an
+ associated aspect instance of a particular type. -->
+ </para>
+
+ <simplelist>
+ <member><literal>args(<replaceable>TypePattern</replaceable> or <replaceable>Id</replaceable> or "..", ...)</literal></member>
+ </simplelist>
+
+ <para>
+ The args pointcut picks out all join points where the arguments are
+ instances of some types. Each element in the comma-separated list is
+ one of three things. If it is a type pattern, then the argument
+ in that position must be an instance of a type of the type name. If
+ it is an identifier, then the argument in that position must be an
+ instance of the type of the identifier (or of any type if the
+ identifier is typed to Object). If it is the special wildcard "..",
+ then any number of arguments will match, just like in signatures. So
+ the pointcut
+ </para>
+
+<programlisting>
+args(int, .., String)
+</programlisting>
+
+ <para>
+ will pick out all join points where the first argument is an
+ <literal>int</literal> and the last is a <literal>String</literal>.
+ </para>
+
+
+ <bridgehead>Control flow-based pointcuts</bridgehead>
+
+ <para>
+ Some concerns cut across the control flow of the program. The cflow
+ and cflowbelow primitive pointcut designators capture join points
+ based on control flow.
+ </para>
+
+ <simplelist>
+ <member><literal>cflow(<replaceable>Pointcut</replaceable>)</literal></member>
+ <member><literal>cflowbelow(<replaceable>Pointcut</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>
+ The cflow pointcut picks out all join points that occur between the start and the
+ end of each of the pointcut's join points.
+ </para>
+
+ <para>
+ The cflowbelow pointcut picks out all join points that occur between
+ the start and the end of each of the pointcut's join points, but
+ not including the initial join point of the control flow itself.
+ </para>
+
+ <bridgehead>Program text-based pointcuts</bridgehead>
+
+ <para>
+ While many concerns cut across the runtime structure of the program,
+ some must deal with the actual lexical structure. AspectJ allows
+ aspects to pick out join points based on where their associated code
+ is defined.
+ </para>
+
+ <simplelist>
+ <member><literal>within(<replaceable>TypePattern</replaceable>)</literal></member>
+ <member><literal>withincode(<replaceable>Signature</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>
+ The within pointcut picks out all join points where the code
+ executing is defined in the declaration of one of the types in
+ <replaceable>TypePattern</replaceable>. This includes the class
+ initialization, object initialization, and method and constructor
+ execution join points for the type, as well as any join points
+ associated with the statements and expressions of the type. It also
+ includes any join points that are associated with code within any of
+ the type's nested types.
+ </para>
+
+ <para>
+ The withincode pointcut picks out all join points where the code
+ executing is defined in the declaration of a particular method or
+ constructor. This includes the method or constructor execution join
+ point as well as any join points associated with the statements and
+ expressions of the method or constructor. It also includes any join
+ points that are associated with code within any of the method or
+ constructor's local or anonymous types.
+ </para>
+
+ <bridgehead>Dynamic property-based pointcuts</bridgehead>
+
+ <simplelist>
+ <member><literal>if(<replaceable>BooleanExpression</replaceable>)</literal></member>
+ </simplelist>
+
+ <para>
+ The if pointcut picks out join points based on a dynamic property.
+ It's syntax takes an expression, which must evaluate to a boolean
+ true or false. Within this expression, the
+ <literal>thisJoinPoint</literal> object is available. So one
+ (extremely inefficient) way of picking out all call join points would
+ be to use the pointcut
+ </para>
+
+<programlisting>
+if(thisJoinPoint.getKind().equals("call"))
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Signatures</title>
+
+ <para>
+ One very important property of a join point is its signature, which is
+ used by many of AspectJ's pointcut designators to select particular
+ join points.
+ </para>
+
+ <para>
+ At a method call join point, the signature is composed of the type used
+ to access the method, the name of the method, and the the types of the called
+ method's formal parameters and return value (if any).
+ </para>
+
+ <para>
+ At a method execution join point, the signature is composed of the type
+ defining the method, the name of the method, and the the types of the executing
+ method's formal parameters and return value (if any).
+ </para>
+
+
+ <para>
+ At a constructor call join point, the signature is composed of the type
+ of the object to be constructed and the types of the
+ called constructor's formal parameters.
+ </para>
+
+ <para>
+ At a constructor execution join point, the signature is composed of the
+ type defining the constructor and the types of the executing
+ constructor's formal parameters.
+ </para>
+
+ <para>
+ At an object initialization join point, the signature is composed of
+ the type being initialized and the types of the formal parameters of
+ the first constructor entered during the initialization of this type.
+ </para>
+
+ <para>
+ At an object pre-initialization join point, the signature is composed
+ of the type being initialized and the types of the formal parameters of
+ the first constructor entered during the initialization of this type.
+ </para>
+
+ <para>
+ At a field reference or assignment join point, the signature is
+ composed of the type used to access or assign to the field, the name of
+ the field, and the type of the field.
+ </para>
+
+ <para>
+ At a handler execution join point, the signature is composed of the
+ exception type that the handler handles.
+ </para>
+
+ <para>
+ The <literal>withincode</literal>, <literal>call</literal>,
+ <literal>execution</literal>, <literal>get</literal>, and
+ <literal>set</literal> primitive pointcut designators all use signature
+ patterns to determine the join points they describe. A signature
+ pattern is an abstract description of one or more join-point
+ signatures. Signature patterns are intended to match very closely the
+ same kind of things one would write when defining individual methods
+ and constructors.
+ </para>
+
+ <para>
+ Method definitions in Java include method names, method parameters,
+ return types, modifiers like static or private, and throws clauses,
+ while constructor definitions omit the return type and replace the
+ method name with the class name. The start of a particular method
+ definition, in class <literal>Test</literal>, for example, might be
+ </para>
+
+
+<programlisting>
+class C {
+ public final void foo() throws ArrayOutOfBoundsException { ... }
+}
+</programlisting>
+
+ <para>
+ In AspectJ, method signature patterns have all these, but most elements
+ can be replaced by wildcards. So
+ </para>
+
+
+<programlisting>
+call(public final void C.foo() throws ArrayOutOfBoundsException)
+</programlisting>
+
+ <para>
+ picks out call join points to that method, and the pointcut
+ </para>
+
+<programlisting>
+call(public final void *.*() throws ArrayOutOfBoundsException)
+</programlisting>
+
+
+ <para>
+ picks out all call join points to methods, regardless of their name
+ name or which class they are defined on, so long as they take no
+ arguments, return no value, are both <literal>public</literal> and
+ <literal>final</literal>, and are declared to throw
+ <literal>ArrayOutOfBounds</literal> exceptions.
+ </para>
+
+ <para>
+ The defining type name, if not present, defaults to *, so another way
+ of writing that pointcut would be
+ </para>
+
+<programlisting>
+call(public final void *() throws ArrayOutOfBoundsException)
+</programlisting>
+
+ <para>
+ Formal parameter lists can use the wildcard <literal>..</literal> to
+ indicate zero or more arguments, so
+ </para>
+
+<programlisting>
+execution(void m(..))
+</programlisting>
+
+ <para>
+ picks out execution join points for void methods named
+ <literal>m</literal>, of any number of arguments, while
+ </para>
+
+<programlisting>
+execution(void m(.., int))
+</programlisting>
+
+
+ <para>
+ picks out execution join points for void methods named
+ <literal>m</literal> whose last parameter is of type
+ <literal>int</literal>.
+ </para>
+
+ <para>
+ The modifiers also form part of the signature pattern. If an AspectJ
+ signature pattern should match methods without a particular modifier,
+ such as all non-public methods, the appropriate modifier should be
+ negated with the <literal>!</literal> operator. So,
+ </para>
+
+<programlisting>
+withincode(!public void foo())
+</programlisting>
+
+ <para>
+ picks out all join points associated with code in null non-public
+ void methods named <literal>foo</literal>, while
+ </para>
+
+<programlisting>
+withincode(void foo())
+</programlisting>
+
+ <para>
+ picks out all join points associated with code in null void methods
+ named <literal>foo</literal>, regardless of access modifier.
+ </para>
+
+ <para>
+ Method names may contain the * wildcard, indicating any number of
+ characters in the method name. So
+ </para>
+
+<programlisting>
+call(int *())
+</programlisting>
+
+ <para>
+ picks out all call join points to <literal>int</literal> methods
+ regardless of name, but
+ </para>
+
+<programlisting>
+call(int get*())
+</programlisting>
+
+ <para>
+ picks out all call join points to <literal>int</literal> methods
+ where the method name starts with the characters "get".
+ </para>
+
+ <para>
+ AspectJ uses the <literal>new</literal> keyword for constructor
+ signature patterns rather than using a particular class name. So the
+ execution join points of private null constructor of a class C
+ defined to throw an ArithmeticException can be picked out with
+ </para>
+
+<programlisting>
+execution(private C.new() throws ArithmeticException)
+</programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Type patterns</title>
+
+ <para>
+ Type patterns are a way to pick out collections of types and use them
+ in places where you would otherwise use only one type. The rules for
+ using type patterns are simple.
+ </para>
+
+ <bridgehead>Type name patterns</bridgehead>
+
+ <para>
+ First, all type names are also type patterns. So
+ <literal>Object</literal>, <literal>java.util.HashMap</literal>,
+ <literal>Map.Entry</literal>, <literal>int</literal> are all type
+ patterns.
+ </para>
+
+ <para>
+ There is a special type name, *, which is also a type pattern. * picks out all
+ types, including primitive types. So
+ </para>
+
+<programlisting>
+call(void foo(*))
+</programlisting>
+
+ <para>
+ picks out all call join points to void methods named foo, taking one
+ argument of any type.
+ </para>
+
+ <para>
+ Type names that contain the two wildcards "*" and
+ "<literal>..</literal>" are also type patterns. The * wildcard matches
+ zero or more characters characters except for ".", so it can be used
+ when types have a certain naming convention. So
+ </para>
+
+<programlisting>
+handler(java.util.*Map)
+</programlisting>
+
+ <para>
+ picks out the types java.util.Map and java.util.java.util.HashMap,
+ among others, and
+ </para>
+
+<programlisting>
+handler(java.util.*)
+</programlisting>
+
+ <para>
+ picks out all types that start with "<literal>java.util.</literal>" and
+ don't have any more "."s, that is, the types in the
+ <literal>java.util</literal> package, but not inner types
+ (such as java.util.Map.Entry).
+ </para>
+
+ <para>
+ The "<literal>..</literal>" wildcard matches any sequence of
+ characters that start and end with a ".", so it can be used
+ to pick out all types in any subpackage, or all inner types. So
+ </para>
+
+<programlisting>
+target(com.xerox..*)
+</programlisting>
+
+ <para>
+ picks out all join points where the target object is an instance of
+ defined in any type beginning with "<literal>com.xerox.</literal>".
+ </para>
+
+ <bridgehead>Subtype patterns</bridgehead>
+
+ <para>
+ It is possible to pick out all subtypes of a type (or a collection of
+ types) with the "+" wildcard. The "+" wildcard follows immediately a
+ type name pattern. So, while
+ </para>
+
+<programlisting>
+call(Foo.new())
+</programlisting>
+
+ <para>
+ picks out all constructor call join points where an instance of exactly
+ type Foo is constructed,
+ </para>
+
+<programlisting>
+call(Foo+.new())
+</programlisting>
+
+ <para>
+ picks out all constructor call join points where an instance of any
+ subtype of Foo (including Foo itself) is constructed, and the unlikely
+ </para>
+
+<programlisting>
+call(*Handler+.new())
+</programlisting>
+
+ <para>
+ picks out all constructor call join points where an instance of any
+ subtype of any type whose name ends in "Handler" is constructed.
+ </para>
+
+ <bridgehead>Array type patterns</bridgehead>
+
+ <para>
+ A type name pattern or subtype pattern can be followed by one or more
+ sets of square brackets to make array type patterns. So
+ <literal>Object[]</literal> is an array type pattern, and so is
+ <literal>com.xerox..*[][]</literal>, and so is
+ <literal>Object+[]</literal>.
+ </para>
+
+ <bridgehead>Type patterns</bridgehead>
+
+ <para>
+ Type patterns are built up out of type name patterns, subtype patterns,
+ and array type patterns, and constructed with boolean operators
+ <literal><![CDATA[&&]]></literal>, <literal>||</literal>, and
+ <literal>!</literal>. So
+ </para>
+
+<programlisting>
+staticinitialization(Foo || Bar)
+</programlisting>
+
+ <para>
+ picks out the static initializer execution join points of either Foo or Bar,
+ and
+ </para>
+
+<programlisting>
+call((Foo+ <![CDATA[&&]]> ! Foo).new(..))
+</programlisting>
+
+ <para>
+ picks out the constructor call join points when a subtype of Foo, but
+ not Foo itself, is constructed.
+ </para>
+ </sect2>
+
+<!-- ============================== -->
+
+ <sect2>
+ <title>Pointcuts and Join Points</title>
+
+ <para>It is possible to pick out every different kind of join point with
+ pointcuts, but some of the less common ones require pointcut
+ combination. </para>
+
+ <sect3>
+ <title>Method call </title> <!-- add chain up -->
+
+<programlisting>
+aspect A {
+ after() returning: call(void foo()) {
+ System.err.println(thisJoinPoint.getKind()); // should be "method-call"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Method execution</title>
+
+<programlisting>
+aspect A {
+ after() returning: execution(void foo()) {
+ System.err.println(thisJoinPoint.getKind()); // should be "method-execution"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Constructor call</title> <!-- add chain up -->
+
+<programlisting>
+aspect A {
+ after() returning: call(Foo.new()) {
+ System.err.println(thisJoinPoint.getKind()); // should be "constructor-call"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Constructor execution<!-- [add chain up] --></title>
+
+<programlisting>
+aspect A {
+ after() returning: execution(Foo.new()) {
+ System.err.println(thisJoinPoint.getKind()); // should be "constructor-execution"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Static initializer execution<!-- [add chain up] --></title>
+
+<programlisting>
+aspect A {
+ after() returning: staticinitializer(Foo) {
+ System.err.println(thisJoinPoint.getKind()); // should be "static-initializar"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Object pre-initialization<!-- [add chain up] --></title>
+
+ <para>This join point will most commonly be seen as the enclosing
+ execution join point of a particular call, since it cannot be simply
+ picked out by AspectJ's primitive pointcuts.</para>
+
+<programlisting>
+aspect A {
+ after() returning: call(Foo) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getKind()); // should be "pre-initialization"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Object initialization<!-- [add chain up] --></title>
+
+
+<programlisting>
+aspect A {
+ after() returning: initialization(Foo.new()) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getKind()); // should be "initialization"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Field Reference <!-- [add chain up] --></title>
+
+
+<programlisting>
+aspect A {
+ after() returning: get(Foo.x) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getKind()); // should be "field-get"
+ }
+}
+</programlisting>
+ </sect3>
+
+ <sect3>
+ <title>Field Assignment <!-- [add chain up] --></title>
+
+
+<programlisting>
+aspect A {
+ after() returning: set(Foo.x) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getKind()); // should be "field-set"
+ }
+}
+</programlisting>
+ </sect3>
+
+
+ <sect3>
+ <title>Handler Execution <!-- [add chain up] --></title>
+
+
+<programlisting>
+aspect A {
+ after() returning: handler(FooExn) {
+ System.err.println(thisEnclosingJoinPointStaticPart.getKind()); // should be "handler"
+ }
+}
+</programlisting>
+ </sect3>
+
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Advice</title>
+
+ <simplelist>
+ <member><literal>before(<replaceable>Formals</replaceable>): <replaceable>Pointcut</replaceable> { <replaceable>Body</replaceable> }</literal></member>
+ <member><literal>after(<replaceable>Formals</replaceable>) returning [ (<replaceable>Formal</replaceable>) ]: <replaceable>Pointcut</replaceable> { <replaceable>Body</replaceable> }</literal></member>
+ <member><literal>after(<replaceable>Formals</replaceable>) throwing [ (<replaceable>Formal</replaceable>) ]: <replaceable>Pointcut</replaceable> { <replaceable>Body</replaceable> }</literal></member>
+ <member><literal>after(<replaceable>Formals</replaceable>) : <replaceable>Pointcut</replaceable> { <replaceable>Body</replaceable> }</literal></member>
+ <member><literal><replaceable>Type</replaceable> around(<replaceable>Formals</replaceable>) [ throws <replaceable>TypeList</replaceable> ] : <replaceable>Pointcut</replaceable> { <replaceable>Body</replaceable> }</literal></member>
+ </simplelist>
+
+ <para>
+ Advice defines crosscutting behavior. It is defined in terms of
+ pointcuts. The code of a piece of advice runs at every join point picked
+ out by its pointcut. Exactly how the code runs depends on the kind of
+ advice.
+ </para>
+
+ <para>
+ AspectJ supports three kinds of advice. The kind of advice determines how
+ it interacts with the join points it is defined over. Thus AspectJ
+ divides advice into that which runs before its join points, that which
+ runs after its join points, and that which runs in place of (or "around")
+ its join points.
+ </para>
+
+ <para>
+ While before advice is relatively unproblematic, there can be three
+ interpretations of after advice: After the execution of a join point
+ completes normally, after it throws an exception, or after it does either
+ one. AspectJ allows after advice for any of these situations.
+ </para>
+
+<programlisting>
+aspect A {
+ pointcut publicCall(): call(public Object *(..));
+ after() returning (Object o): publicCall() {
+ System.out.println("Returned normally with " + o);
+ }
+ after() throwing (Exception e): publicCall() {
+ System.out.println("Threw an exception: " + e);
+ }
+ after(): publicCall(){
+ System.out.println("Returned or threw an Exception");
+ }
+}
+</programlisting>
+
+ <para>
+ After returning advice may not care about its returned object, in which
+ case it may be written
+ </para>
+
+<programlisting>
+after() returning: call(public Object *(..)) {
+ System.out.println("Returned normally");
+}
+</programlisting>
+
+ <para>
+ It is an error to try to put after returning advice on a join point that
+ does not return the correct type. For example,
+ </para>
+
+<programlisting>
+after() returning (byte b): call(int String.length()) {
+ // this is an error
+}
+</programlisting>
+
+ <para>
+ is not allowed. But if no return value is exposed, or the exposed return
+ value is typed to <literal>Object</literal>, then it may be applied to
+ any join point. If the exposed value is typed to
+ <literal>Object</literal>, then the actual return value is converted to
+ an object type for the body of the advice: <literal>int</literal> values
+ are represented as <literal>java.lang.Integer</literal> objects, etc, and
+ no value (from void methods, for example) is represented as
+ <literal>null</literal>.
+ </para>
+
+ <para>
+ Around advice runs in place of the join point it operates over, rather
+ than before or after it. Because around is allowed to return a value, it
+ must be declared with a return type, like a method. A piece of around
+ advice may be declared <literal>void</literal>, in which case it is not
+ allowed to return a value, and instead whatever value the join point
+ returned will be returned by the around advice (unless the around advice
+ throws an exception of its own).
+ </para>
+
+ <para>
+ Thus, a simple use of around advice is to make a particular method
+ constant:
+ </para>
+
+<programlisting>
+aspect A {
+ int around(): call(int C.foo()) {
+ return 3;
+ }
+}
+</programlisting>
+
+ <para>
+ Within the body of around advice, though, the computation of the original
+ join point can be executed with the special syntax
+ </para>
+
+<programlisting>
+proceed( ... )
+</programlisting>
+
+ <para>
+ The proceed form takes as arguments the context exposed by the around's
+ pointcut, and returns whatever the around is declared to return. So the
+ following around advice will double the second argument to
+ <literal>foo</literal> whenever it is called, and then halve its result:
+ </para>
+
+
+<programlisting>
+aspect A {
+ int around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) {
+ int newi = proceed(i*2)
+ return newi/2;
+ }
+}
+</programlisting>
+
+ <para>
+ If the return value of around advice is typed to
+ <literal>Object</literal>, then the result of proceed is converted to an
+ object representation, even if it is originally a primitive value. And
+ when the advice returns an Object value, that value is converted back to
+ whatever representation it was originally. So another way to write the
+ doubling and halving advice is:
+ </para>
+
+<programlisting>
+aspect A {
+ Object around(int i): call(int C.foo(Object, int)) <![CDATA[&&]]> args(i) {
+ Integer newi = (Integer) proceed(i*2)
+ return new Integer(newi.intValue() / 2);
+ }
+}
+</programlisting>
+
+ <para>
+ In all kinds of advice, the parameters of the advice behave exactly like
+ method parameters. In particular, assigning to any parameter affects
+ only the value of the parameter, not the value that it came from. This
+ means that
+ </para>
+
+<programlisting>
+aspect A {
+ after() returning (int i): call(int C.foo()) {
+ i = i * 2;
+ }
+}
+</programlisting>
+
+ <para>
+ will <emphasis>not</emphasis> double the returned value of the advice.
+ Rather, it will double the local parameter. Changing the values of
+ parameters or return values of join points can be done by using around
+ advice.
+ </para>
+
+ <sect2>
+ <title>Advice modifiers</title>
+
+ <para>
+ The <literal>strictfp</literal> modifier is the only modifier allowed
+ on advice, and it has the effect of making all floating-point
+ expressions within the advice be FP-strict.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Advice and checked exceptions</title>
+
+ <para>
+ An advice declaration must include a <literal>throws</literal> clause
+ listing the checked exceptions the body may throw. This list of
+ checked exceptions must be compatible with each target join point
+ of the advice, or an error is signalled by the compiler.
+ </para>
+
+ <para>
+ For example, in the following declarations:
+ </para>
+
+<programlisting>
+import java.io.FileNotFoundException;
+
+class C {
+ int i;
+
+ int getI() { return i; }
+}
+
+aspect A {
+ before(): get(int C.i) {
+ throw new FileNotFoundException();
+ }
+ before() throws FileNotFoundException: get(int C.i) {
+ throw new FileNotFoundException();
+ }
+}
+</programlisting>
+
+ <para>
+ both pieces of advice are illegal. The first because the body throws
+ an undeclared checked exception, and the second because field get join
+ points cannot throw <literal>FileNotFoundException</literal>s.
+ </para>
+
+ <para> The exceptions that each kind of join point in AspectJ may throw are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term>method call and execution</term>
+ <listitem>
+ <para>the checked exceptions declared by the target method's
+ <literal>throws</literal> clause.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>constructor call and execution</term>
+ <listitem>
+ <para>the checked exceptions declared by the target constructor's
+ <literal>throws</literal> clause.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>field get and set</term>
+ <listitem>
+ <para>no checked exceptions can be thrown from these join points. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>exception handler execution</term>
+ <listitem>
+ <para>the exceptions that can be thrown by the target exception handler.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>static initializer execution</term>
+ <listitem>
+ <para>no checked exceptions can be thrown from these join points. </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>initializer execution, pre-initialization, and initialization</term>
+ <listitem>
+ <para>any exception that is in the throws clause of
+ <emphasis>all</emphasis> constructors of the initialized class. </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </sect2>
+
+
+ <sect2>
+ <title>Advice precedence</title>
+
+ <para>
+ Multiple pieces of advice may apply to the same join point. In such
+ cases, the resolution order of the advice is based on advice
+ precedence.
+ </para>
+
+ <sect3>
+ <title>Determining precedence</title>
+
+ <para>There are a number of rules that determine whether a particular
+ piece of advice has precedence over another when they advise the same
+ join point. </para>
+
+ <para>If the two pieces of advice are defined in different aspects,
+ then there are three cases: </para>
+
+ <simplelist>
+ <member>If aspect A is declared such that it <literal>dominates</literal>
+ aspect B, then all advice defined in A has precedence over all advice
+ defined in
+ B. </member>
+
+ <member>
+ Otherwise, if aspect A is a subaspect of aspect B, then all advice
+ defined in A has precedence over all advice defined in
+ B. So, unless otherwise specified with a
+ <literal>dominates</literal> keyword, advice in a subaspect
+ dominates advice in a superaspect.
+ </member>
+
+ <member>
+ Otherwise, if two pieces of advice are defined in two different
+ aspects, it is undefined which one has precedence.
+ </member>
+
+ </simplelist>
+
+ <para>If the two pieces of advice are defined in the same aspect, then
+ there are two cases: </para>
+
+ <simplelist>
+ <member>If either are <literal>after</literal> advice, then the one that
+ appears later in the aspect has precedence over the one that appears
+ earlier. </member>
+
+ <member>Otherwise, then the one that appears earlier in the aspect
+ has precedence over the one that appears later.
+ </member>
+
+ </simplelist>
+
+ <para>These rules can lead to circularity, such as</para>
+
+<programlisting>
+aspect A {
+ before(): execution(void main(String[] args)) {}
+ after(): execution(void main(String[] args)) {}
+ before(): execution(void main(String[] args)) {}
+}
+</programlisting>
+
+ <para>such circularities will result in errors signalled by the compiler. </para>
+
+ </sect3>
+
+ <sect3>
+ <title>Effects of precedence</title>
+
+ <para>At a particular join point, advice is ordered by precedence.</para>
+
+ <para>A piece of <literal>around</literal> advice controls whether
+ advice of lower precedence will run by calling
+ <literal>proceed</literal>. The call to <literal>proceed</literal>
+ will run the advice with next precedence, or the computation under the
+ join point if there is no further advice. </para>
+
+ <para>A piece of <literal>before</literal> advice can prevent advice of
+ lower precedence from running by throwing an exception. If it returns
+ normally, however, then the advice of the next precedence, or the
+ computation under the join pint if there is no further advice, will run.
+ </para>
+
+ <para>Running <literal>after returning</literal> advice will run the
+ advice of next precedence, or the computation under the join point if
+ there is no further advice. Then, if that computation returned
+ normally, the body of the advice will run. </para>
+
+ <para>Running <literal>after throwing</literal> advice will run the
+ advice of next precedence, or the computation under the join
+ point if there is no further advice. Then, if that computation threw
+ an exception of an appropriate type, the body of the advice will
+ run. </para>
+
+ <para>Running <literal>after</literal> advice will run the advice of
+ next precedence, or the computation under the join point if
+ there is no further advice. Then the body of the advice will
+ run. </para>
+ </sect3>
+
+ </sect2>
+
+ <sect2>
+ <title>Reflective access to the join point</title>
+
+ <para>
+ Three special variables are visible within bodies of advice:
+ <literal>thisJoinPoint</literal>,
+ <literal>thisJoinPointStaticPart</literal>, and
+ <literal>thisEnclosingJoinPointStaticPart</literal>. Each is bound to
+ an object that encapsulates some of the context of the advice's current
+ or enclosing join point. These variables exist because some pointcuts
+ may pick out very large collections of join points. For example, the
+ pointcut
+ </para>
+
+
+<programlisting>
+pointcut publicCall(): call(public * *(..));
+</programlisting>
+
+
+ <para>
+ picks out calls to many methods. Yet the body of advice over this
+ pointcut may wish to have access to the method name or parameters of a
+ particular join point.
+ </para>
+
+ <para>
+ <literal>thisJoinPoint</literal> is bound to a complete join point
+ object, while <literal>thisJoinPointStaticPart</literal> is bound to a
+ part of the join point object that includes less information,
+ but for which no memory allocation is required on each execution of the
+ advice.
+ </para>
+
+ <para>
+ <literal>thisEnclosingJoinPointStaticPart</literal> is bound to the
+ static part of the join point enclosing the current join point. Only
+ the static part of this enclosing join point is available through this
+ mechanism.
+ </para>
+
+ <para>
+ Like standard Java reflection, which uses objects from the
+ <literal>java.lang.reflect</literal> hierarchy, join point objects have
+ types in a type hierarchy. The type of objects bound to
+ <literal>thisJoinPoint</literal> is
+ <literal>org.aspectj.lang.JoinPoint</literal>, while
+ <literal>thisStaticJoinPoint</literal> is bound to objects of interface
+ type <literal>org.aspectj.lang.JoinPoint.StaticPart</literal>.
+ </para>
+ </sect2>
+
+ </sect1>
+
+ <sect1>
+ <title>Static crosscutting</title>
+
+ <para>
+ Advice declarations change the behavior of classes they crosscut, but do
+ not change their static type structure. For crosscutting concerns that do
+ operate over the static structure of type hierarchies, AspectJ provides
+ forms of introduction.
+ </para>
+
+ <para>
+ Each introduction form is a member of the aspect defining it, but defines
+ a new member of another type.
+ </para>
+
+ <sect2>
+ <title>Member introduction</title>
+
+ <para>
+ A method introduction looks like
+ </para>
+
+ <simplelist>
+ <member><literal><replaceable>Modifiers</replaceable>
+ <replaceable>Type</replaceable> <replaceable>TypePattern</replaceable>
+ .
+ <replaceable>Id</replaceable>(<replaceable>Formals</replaceable>)
+ { <replaceable>Body</replaceable> }</literal></member>
+
+ <member><literal>abstract <replaceable>Modifiers</replaceable>
+ <replaceable>Type</replaceable> <replaceable>TypePattern</replaceable>
+ . <replaceable>Id</replaceable>(<replaceable>Formals</replaceable>);
+ </literal></member>
+ </simplelist>
+
+ <para>
+ The effect of such an introduction is to make all the types in TypePattern
+ support the new method. Interfaces in TypePattern will support the new method
+ as well, even if the method is neither public nor abstract, so the
+ following is legal AspectJ code:
+ </para>
+
+<programlisting>
+interface Iface {}
+
+aspect A {
+ private void Iface.m() {
+ System.err.println("I'm a private method on an interface");
+ }
+ void worksOnI(Iface iface) {
+ // calling a private method on an interface
+ iface.m();
+ }
+}
+</programlisting>
+
+ <para>
+ A constructor introduction looks like
+ </para>
+
+ <simplelist>
+ <member><literal><replaceable>Modifiers</replaceable> <replaceable>TypePattern</replaceable>.new(<replaceable>Formals</replaceable>)
+ { <replaceable>Body</replaceable> }</literal></member>
+ </simplelist>
+
+ <para>
+ The effect of such an introduction is to make all the types in
+ TypePattern support the new constructor. You cannot introduce a
+ constructor onto an interface, so if TypePattern includes an interface
+ type it is an error.
+ </para>
+
+ <para>
+ A field introduction looks like one of
+ </para>
+
+ <simplelist>
+ <member><literal><replaceable>Modifiers</replaceable>
+ <replaceable>Type</replaceable> <replaceable>TypePattern</replaceable>.<replaceable>Id</replaceable> = <replaceable>Expression</replaceable>;</literal></member>
+
+ <member><literal><replaceable>Modifiers</replaceable>
+ <replaceable>Type</replaceable> <replaceable>TypePattern</replaceable>.<replaceable>Id</replaceable>;</literal></member>
+ </simplelist>
+
+ <para>
+ The effect of such an introduction is to make all the types in
+ TypePattern support the new field. Interfaces in TypePattern will
+ support the new field as well, even if the field is neither public,
+ nor static, nor final.
+ </para>
+ </sect2>
+
+ <para>
+ Any occurrence of the identifier <literal>this</literal> in the body of
+ the constructor or method introduction, or in the initializer of a
+ field introduction, refers to the target type from the
+ <replaceable>TypePattern</replaceable> rather than to the aspect type.
+ </para>
+
+
+ <sect2>
+ <title>Access modifiers</title>
+
+ <para>
+ Members may be introduced with access modifiers public or private, or
+ the default package-protected (protected introduction is not
+ supported).
+ </para>
+
+ <para>
+ The access modifier applies in relation to the aspect, not in relation
+ to the target type. So a member that is privately introduced is visible
+ only from code that is defined within the aspect introducing it. One
+ that is package-protectedly introduced is visible only from code that
+ is defined within the introducing aspect's package.
+ </para>
+
+ <para>
+ Note that privately introducing a method (which AspectJ supports) is
+ very different from introducing a private method (which AspectJ
+ previously supported). AspectJ does not allow the introduction of the
+ private method "void writeObject(ObjectOutputStream)" required to
+ implement the interface java.io.Serializable.
+ </para>
+ </sect2>
+
+ <sect2>
+ <title>Conflicts</title>
+
+ <para>
+ Introduction may cause conflicts among introduced members and between
+ introduced members and defined members.
+ </para>
+
+
+ <para>
+ Assuming <literal>otherPackage</literal> is not the package defining
+ the aspect <classname>A</classname>, the code
+ </para>
+
+<programlisting>
+aspect A {
+ private Registry otherPackage.*.r;
+ public void otherPackage.*.register(Registry r) {
+ r.register(this);
+ this.r = r;
+ }
+}
+</programlisting>
+
+ <para>
+ adds a field "<literal>r</literal>" to every type in otherPackage. This
+ field is only accessible from the code inside of aspect
+ <literal>A</literal>. The aspect also adds a
+ "<literal>register</literal>" method to every type in
+ <literal>otherPackage</literal>. This method is accessible
+ everywhere.
+ </para>
+
+ <para>
+ If any type in <literal>otherPackage</literal> already defines a
+ private or package-protected field "<literal>r</literal>", there is no
+ conflict: The aspect cannot see such a field, and no code in
+ <literal>otherPackage</literal> can see the introduced
+ "<literal>r</literal>".
+ </para>
+
+ <para>
+ If any type in <literal>otherPackage</literal> defines a public field
+ "<literal>r</literal>", there is a conflict: The expression
+ </para>
+
+<programlisting>
+this.r = r
+</programlisting>
+
+ <para>
+ is an error, since it is ambiguous whether the introduced
+ "<literal>r</literal>" or the public "<literal>r</literal>" should be
+ used.
+ </para>
+
+ <para>
+ If any type in <literal>otherPackage</literal> defines any method
+ "<literal>register(Registry)</literal>" there is a conflict, since it
+ would be ambiguous to any code that could see such a defined method
+ which "<literal>register(Registry)</literal>" method was applicable.
+ </para>
+
+ <para>
+ Conflicts are resolved as much as possible as per Java's conflict
+ resolution rules:
+ </para>
+
+ <simplelist>
+ <member>A subclass can inherit multiple <emphasis>fields</emphasis> from its superclasses,
+ all with the same name and type. However, it is an error to have an ambiguous
+ <emphasis>reference</emphasis> to a field.</member>
+
+ <member>A subclass can only inherit multiple
+ <emphasis>methods</emphasis> with the same name and argument types from
+ its superclasses if only zero or one of them is concrete (i.e., all but
+ one is abstract, or all are abstract).
+ </member>
+ </simplelist>
+
+ <para>
+ Given a potential conflict between inter-type member declarations in
+ different aspects, if one aspect dominates the other its declaration will
+ take effect without any conflict notice from compiler. This is true both
+ when the domination is declared explicitly in a "dominates" clause and
+ when sub-aspects implicitly dominate their corresponding super-aspect.
+ </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Extension and Implementation</title>
+
+ <para>
+ An aspect may introduce a superclass or superinterface onto a type,
+ with the declarations
+ </para>
+
+ <simplelist>
+ <member><literal>declare parents: <replaceable>TypePattern</replaceable> extends <replaceable>TypeList</replaceable>;</literal></member>
+ <member><literal>declare parents: <replaceable>TypePattern</replaceable> implements <replaceable>TypeList</replaceable>;</literal></member>
+ </simplelist>
+
+ <para>
+ For example, if an aspect wished to make a particular class runnable,
+ it might add an appropriate <literal>void run()</literal> method, but
+ it should also change the type of the class to specify that it fulfills
+ the <literal>Runnable</literal> interface. In order to implement the
+ methods in the <literal>Runnable</literal> interface, the
+ <literal>run()</literal> method must be publically introduced:
+ </para>
+
+<programlisting>
+aspect A {
+ declare parents: SomeClass implements Runnable;
+ public void SomeClass.run() { ... }
+}
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Interfaces with members</title>
+
+ <para>
+ Through the use of introduction, interfaces may now carry
+ (non-public-static-final) fields and (non-public-abstract) methods that
+ classes can inherit. Conflicts may occur from ambiguously inheriting
+ members from a superclass and multiple superinterfaces.
+ </para>
+
+ <para>
+ Because interfaces may carry non-static initializers, the order of
+ super-interface instantiation is observable. We fix this order with the
+ following three properties: A supertype is initialized before a
+ subtype, that initialized code runs only once, and initializers for
+ supertypes run in left-to-right order. Consider the following hierarchy
+ where {<literal>Object</literal>, <literal>C</literal>,
+ <literal>D</literal>, <literal>E</literal>} are classes,
+ {<literal>M</literal>, <literal>N</literal>, <literal>O</literal>,
+ <literal>P</literal>, <literal>Q</literal>} are interfaces.
+ </para>
+
+<programlisting>
+ Object M O
+ \ / \ /
+ C N Q
+ \ / /
+ D P
+ \ /
+ E
+</programlisting>
+
+ <para>
+ when a new <literal>E</literal> is instantiated, the initializers run in this order:
+ </para>
+
+<programlisting>
+ Object M C O N D Q P E
+</programlisting>
+
+ </sect2>
+
+ <sect2>
+ <title>Warnings and Errors</title>
+
+ <para>An aspect may specify that a particular join point should never be
+ reached. </para>
+
+ <simplelist>
+ <member><literal>declare error: <replaceable>Pointcut</replaceable>: <replaceable>String</replaceable>;</literal></member>
+ <member><literal>declare warning: <replaceable>Pointcut</replaceable>: <replaceable>String</replaceable>;</literal></member>
+ </simplelist>
+
+ <para>If the compiler determines that a join point in
+ <replaceable>Pointcut</replaceable> could possibly be reached, then it
+ will signal either an error or warning, as declared, using the
+ <replaceable>String</replaceable> for its message. </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Softened exceptions</title>
+
+ <para>An aspect may specify that a particular kind of exception, if
+ thrown at a join point, should bypass Java's usual static exception
+ checking system and instead be thrown as a
+ <literal>org.aspectj.lang.SoftException</literal>, which is subtype of
+ <literal>RuntimeException</literal> and thus does not need to be
+ declared. </para>
+
+ <simplelist>
+ <member><literal>declare soft: <replaceable>TypePattern</replaceable>: <replaceable>Pointcut</replaceable>;</literal></member>
+ </simplelist>
+
+ <para>For example, the aspect</para>
+
+<programlisting>
+aspect A {
+ declare soft: Exception: execution(void main(String[] args));
+}
+</programlisting>
+
+ <para>Would, at the execution join point, catch any
+ <literal>Exception</literal> and rethrow a
+ <literal>org.aspectj.lang.SoftException</literal> containing
+ original exception. </para>
+
+ <para>This is similar to what the following advice would do</para>
+
+<programlisting>
+aspect A {
+ void around() execution(void main(String[] args)) {
+ try { proceed(); }
+ catch (Exception e) {
+ throw new org.aspectj.lang.SoftException(e);
+ }
+ }
+}
+</programlisting>
+
+ <para>except, in addition to wrapping the exception, it also affects
+ Java's static exception checking mechanism. </para>
+
+ </sect2>
+
+ <sect2>
+ <title>Statically determinable pointcuts</title>
+
+ <para>Pointcuts that appear inside of <literal>declare</literal> forms
+ have certain restrictions. Like other pointcuts, these pick out join
+ points, but they do so in a way that is statically determinable. </para>
+
+ <para>Consequently, such pointcuts may not include, directly or
+ indirectly (through user-defined pointcut declarations) pointcuts that
+ discriminate based on dynamic (runtime) context. Therefore, such
+ pointcuts may not be defined in terms of</para>
+
+ <simplelist>
+ <member>cflow</member>
+ <member>cflowbelow</member>
+ <member>this</member>
+ <member>target</member>
+ <member>args</member>
+ <member>if</member>
+ </simplelist>
+
+ <para> all of which can discriminate on runtime information. </para>
+ </sect2>
+ </sect1>
+
+ <sect1>
+ <title>Aspects</title>
+
+ <para>
+ An aspect is a crosscutting type defined by the aspect declaration. The
+ aspect declaration is similar to the class declaration in that it defines
+ a type and an implementation for that type. It differs in that the type
+ and implementation can cut across other types (including those defined by
+ other aspect declarations), and that it may not be directly instantiated
+ with a new expression, with cloning, or with serialization. Aspects may
+ have one constructor definition, but if so it must be of a constructor
+ taking no arguments and throwing no checked exceptions.
+ </para>
+
+ <para>
+ Aspects may be defined either at the package level, or as a static nested
+ aspect, that is, a static member of a class, interface, or aspect. If it
+ is not at the package level, the aspect <emphasis>must</emphasis> be
+ defined with the static keyword. Local and anonymous aspects are not
+ allowed.
+ </para>
+
+ <sect2>
+ <title>Aspect Extension</title>
+
+ <para>
+ To support abstraction and composition of crosscutting concerns,
+ aspects can be extended in much the same way that classes can. Aspect
+ extension adds some new rules, though.
+ </para>
+
+ <sect3>
+ <title>Aspects may extend classes and implement interfaces</title>
+
+ <para>
+ An aspect, abstract or concrete, may extend a class and may implement
+ a set of interfaces. Extending a class does not provide the ability
+ to instantiate the aspect with a new expression: The aspect may still
+ only define a null constructor.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Classes may not extend aspects</title>
+
+ <para>
+ It is an error for a class to extend or implement an aspect.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Aspects extending aspects
+ </title>
+ <para>
+ Aspects may extend other aspects, in which case not only are fields
+ and methods inherited but so are pointcuts. However, aspects may only
+ extend abstract aspects. It is an error for a concrete aspect to
+ extend another concrete aspect.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Aspect instantiation</title>
+
+ <para>
+ Unlike class expressions, aspects are not instantiated with
+ <literal>new</literal> expressions. Rather, aspect instances are
+ automatically created to cut across programs.
+ </para>
+
+ <para>
+ Because advice only runs in the context of an aspect instance, aspect
+ instantiation indirectly controls when advice runs.
+ </para>
+
+ <para>
+ The criteria used to determine how an aspect is instantiated
+ is inherited from its parent aspect. If the aspect has no parent
+ aspect, then by default the aspect is a singleton aspect.
+ </para>
+
+ <sect3>
+ <title>Singleton Aspects</title>
+
+ <simplelist>
+ <member><literal>aspect <replaceable>Id</replaceable> { ... }</literal></member>
+ <member><literal>aspect <replaceable>Id</replaceable> issingleton { ... }</literal></member>
+ </simplelist>
+
+ <para>
+ By default, or by using the modifier <literal>issingleton</literal>, an
+ aspect has exactly one instance that cuts across the entire program.
+ That instance is available at any time during program execution with
+ the static method <literal>aspectOf()</literal> defined on the aspect
+ -- so, in the above examples, <literal>A.aspectOf()</literal> will
+ return A's instance. This aspect instance is created as the aspect's
+ classfile is loaded.
+ </para>
+
+ <para>
+ Because the an instance of the aspect exists at all join points in
+ the running of a program (once its class is loaded), its advice will
+ have a chance to run at all such join points.
+ </para>
+ </sect3>
+
+ <sect3>
+ <title>Per-object aspects</title>
+
+ <simplelist>
+ <member><literal>aspect <replaceable>Id</replaceable> perthis(<replaceable>Pointcut</replaceable>) { ... }</literal></member>
+ <member><literal>aspect <replaceable>Id</replaceable> pertarget(<replaceable>Pointcut</replaceable>) { ... }</literal></member>
+ </simplelist>
+
+ <para>
+ If an aspect A is defined
+ <literal>perthis(<replaceable>Pointcut</replaceable>)</literal>, then
+ one object of type A is created for every object that is the
+ executing object (i.e., "this") at any of the join points picked out
+ by <replaceable>Pointcut</replaceable>.
+ The advice defined in A may then run at any join point where the
+ currently executing object has been associated with an instance of
+ A.
+ </para>
+
+ <para> Similarly, if an aspect A is defined
+ <literal>pertarget(<replaceable>Pointcut</replaceable>)</literal>,
+ then one object of type A is created for every object that is the
+ target object of the join points picked out by
+ <replaceable>Pointcut</replaceable>.
+ The advice defined in A may then run at any join point where the
+ target object has been associated with an instance of
+ A.
+ </para>
+
+ <para>
+ In either case, the static method call
+ <literal>A.aspectOf(Object)</literal> can be used to get the aspect
+ instance (of type A) registered with the object. Each aspect
+ instance is created as early as possible, but not before reaching a
+ join point picked out by <replaceable>Pointcut</replaceable> where
+ there is no associated aspect of type A.
+ </para>
+
+ <para> Both <literal>perthis</literal> and <literal>pertarget</literal>
+ aspects may be affected by code the AspectJ compiler controls, as
+ discussed in the <xref linkend="limitations"/> appendix. </para>
+
+ </sect3>
+
+ <sect3>
+ <title>Per-control-flow aspects</title>
+
+ <simplelist>
+ <member><literal>aspect <replaceable>Id</replaceable> percflow(<replaceable>Pointcut</replaceable>) { ... }</literal></member>
+ <member><literal>aspect <replaceable>Id</replaceable> percflowbelow(<replaceable>Pointcut</replaceable>) { ... }</literal></member>
+ </simplelist>
+
+ <para>
+ If an aspect A is defined
+ <literal>percflow(<replaceable>Pointcut</replaceable>)</literal> or
+ <literal>percflowbelow(<replaceable>Pointcut</replaceable>)</literal>,
+ then one object of type A is created for each flow of control of the
+ join points picked out by <replaceable>Pointcut</replaceable>, either
+ as the flow of control is entered, or below the flow of control,
+ respectively. The advice defined in A may run at any join point in
+ or under that control flow. During each such flow of control, the
+ static method <literal>A.aspectOf()</literal> will return an object
+ of type
+ A. An instance of the aspect is created upon entry into each such
+ control flow.
+ </para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Aspect privilege</title>
+
+ <simplelist>
+ <member><literal>privileged aspect <replaceable>Id</replaceable> { ... }</literal></member>
+ </simplelist>
+
+ <para>
+ Code written in aspects is subject to the same access control rules as
+ Java code when referring to members of classes or aspects. So, for
+ example, code written in an aspect may not refer to members with
+ default (package-protected) visibility unless the aspect is defined in
+ the same package.
+ </para>
+
+ <para>
+ While these restrictions are suitable for many aspects, there may be
+ some aspects in which advice or introductions needs to access private
+ or protected resources of other types. To allow this, aspects may be
+ declared <literal>privileged</literal>. Code in priviliged aspects has
+ access to all members, even private ones.
+ </para>
+
+
+<programlisting>
+class C {
+ private int i = 0;
+ void incI(int x) { i = i+x; }
+}
+privileged aspect A {
+ static final int MAX = 1000;
+ before(int x, C c): call(void C.incI(int)) <![CDATA[&&]]> target(c) <![CDATA[&&]]> args(x) {
+ if (c.i+x &gt; MAX) throw new RuntimeException();
+ }
+}
+</programlisting>
+
+ <para>
+ In this case, if A had not been declared privileged, the field reference
+ c.i would have resulted in an error signalled by the compiler.
+ </para>
+
+ <para>
+ If a privileged aspect can access multiple versions of a particular
+ member, then those that it could see if it were not privileged take
+ precedence. For example, in the code
+ </para>
+
+<programlisting>
+class C {
+ private int i = 0;
+ void foo() { }
+}
+privileged aspect A {
+ private int C.i = 999;
+ before(C c): call(void C.foo()) target(c) {
+ System.out.println(c.i);
+ }
+}
+</programlisting>
+
+ <para>
+ A's introduced private field C.i, initially bound to 999, will be
+ referenced in the body of the advice in preference to C's privately
+ declared field, since the A would have access to fields it introduces
+ even if it were not privileged.
+ </para>
+
+ </sect2>
+
+
+ <sect2>
+ <title>Aspect domination</title>
+
+ <simplelist>
+ <member><literal>aspect <replaceable>Id</replaceable> dominates <replaceable>TypePattern</replaceable> { ... }</literal></member>
+ </simplelist>
+
+ <para>
+ An aspect may declare that the advice in it dominates the advice in
+ some other aspect. Such declarations are like the
+ <literal>strictfp</literal> keyword in Java; it applies to the advice
+ declarations inside of the respective aspects, and states that the
+ advice declared in the current aspect has more precedence than the
+ advice in the aspects from <replaceable>TypePattern</replaceable>.
+ </para>
+
+ <para>
+ For example, the CountEntry aspect might want to count the entry to
+ methods in the current package accepting a Type object as its first
+ argument. However, it should count all entries, even those that the
+ aspect DisallowNulls causes to throw exceptions. This can be
+ accomplished by stating that CountEntry dominates DisallowNulls.
+ </para>
+
+
+<programlisting>
+aspect DisallowNulls {
+ pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..);
+ before(Type obj): allTypeMethods(obj) {
+ if (obj == null) throw new RuntimeException();
+ }
+}
+aspect CountEntry dominates DisallowNulls {
+ pointcut allTypeMethods(Type obj): call(* *(..)) <![CDATA[&&]]> args(obj, ..);
+ static int count = 0;
+ before(): allTypeMethods(Type) {
+ count++;
+ }
+}
+</programlisting>
+
+ </sect2>
+ </sect1>
+
+</appendix>
+
+<!--
+Local variables:
+compile-command: "java sax.SAXCount -v progguide.xml && java com.icl.saxon.StyleSheet -w0 progguide.xml progguide.html.xsl"
+fill-column: 79
+sgml-local-ecat-files: progguide.ced
+sgml-parent-document:("progguide.sgml" "book" "appendix")
+End:
+-->
diff --git a/docs/progGuideDB/telecom.gif b/docs/progGuideDB/telecom.gif
new file mode 100644
index 000000000..89a7207f3
--- /dev/null
+++ b/docs/progGuideDB/telecom.gif
Binary files differ