aboutsummaryrefslogtreecommitdiffstats
path: root/docs
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
parent3ce247199704eae6b2c92c6e38c69584e3250c52 (diff)
downloadaspectj-d842c4f1139629c1f062b74ba818d233b2c31043.tar.gz
aspectj-d842c4f1139629c1f062b74ba818d233b2c31043.zip
initial version
Diffstat (limited to 'docs')
-rw-r--r--docs/build.xml399
-rw-r--r--docs/devGuideDB/ajbrowser-building.gifbin0 -> 26404 bytes
-rw-r--r--docs/devGuideDB/ajbrowser-options.gifbin0 -> 9437 bytes
-rw-r--r--docs/devGuideDB/ajbrowser.xml222
-rw-r--r--docs/devGuideDB/ajc.xml484
-rw-r--r--docs/devGuideDB/ajdb.xml312
-rw-r--r--docs/devGuideDB/ajdee.gifbin0 -> 21193 bytes
-rw-r--r--docs/devGuideDB/ajdee.xml452
-rw-r--r--docs/devGuideDB/ajdeforte.xml215
-rw-r--r--docs/devGuideDB/ajdejbuilder.xml266
-rw-r--r--docs/devGuideDB/ajdoc.xml155
-rw-r--r--docs/devGuideDB/antsupport.xml23
-rw-r--r--docs/devGuideDB/aspectj-mode.gifbin0 -> 11988 bytes
-rw-r--r--docs/devGuideDB/aspectj-mode.xml354
-rw-r--r--docs/devGuideDB/aspectj-mode2.gifbin0 -> 20913 bytes
-rw-r--r--docs/devGuideDB/devguide.xml69
-rw-r--r--docs/devGuideDB/jbuilder-buildOptions.gifbin0 -> 10064 bytes
-rw-r--r--docs/devGuideDB/jbuilder-building.gifbin0 -> 27587 bytes
-rw-r--r--docs/devGuideDB/jbuilder-configs.gifbin0 -> 24200 bytes
-rw-r--r--docs/devGuideDB/jbuilder-structureNavigation.gifbin0 -> 30813 bytes
-rw-r--r--docs/devGuideDB/netbeans-buildOptions.gifbin0 -> 10273 bytes
-rw-r--r--docs/devGuideDB/netbeans-building.gifbin0 -> 33075 bytes
-rw-r--r--docs/dist/doc/ant-ajc-task.html389
-rw-r--r--docs/dist/doc/ant-ajc10-task.html383
-rw-r--r--docs/dist/doc/ant-tasks.html230
-rw-r--r--docs/dist/doc/changes.html1502
-rw-r--r--docs/dist/doc/index.html329
-rw-r--r--docs/dist/doc/porting.html1785
-rw-r--r--docs/dist/doc/quick.docbin0 -> 56832 bytes
-rw-r--r--docs/dist/examples/bean/BoundPoint.java93
-rw-r--r--docs/dist/examples/bean/Demo.java83
-rw-r--r--docs/dist/examples/bean/Point.java76
-rw-r--r--docs/dist/examples/build.xml282
-rw-r--r--docs/dist/examples/coordination/Condition.java37
-rw-r--r--docs/dist/examples/coordination/CoordinationAction.java37
-rw-r--r--docs/dist/examples/coordination/Coordinator.java449
-rw-r--r--docs/dist/examples/coordination/Exclusion.java33
-rw-r--r--docs/dist/examples/coordination/MethodState.java45
-rw-r--r--docs/dist/examples/coordination/Mutex.java86
-rw-r--r--docs/dist/examples/coordination/Selfex.java55
-rw-r--r--docs/dist/examples/coordination/TimeoutException.java27
-rw-r--r--docs/dist/examples/introduction/CloneablePoint.java42
-rw-r--r--docs/dist/examples/introduction/ComparablePoint.java46
-rw-r--r--docs/dist/examples/introduction/HashablePoint.java47
-rw-r--r--docs/dist/examples/introduction/Point.java98
-rw-r--r--docs/dist/examples/observer/Button.java45
-rw-r--r--docs/dist/examples/observer/ColorLabel.java40
-rw-r--r--docs/dist/examples/observer/Demo.java34
-rw-r--r--docs/dist/examples/observer/Display.java52
-rw-r--r--docs/dist/examples/observer/Observer.java22
-rw-r--r--docs/dist/examples/observer/Subject.java24
-rw-r--r--docs/dist/examples/observer/SubjectObserverProtocol.java47
-rw-r--r--docs/dist/examples/observer/SubjectObserverProtocolImpl.java36
-rw-r--r--docs/dist/examples/spacewar/Bullet.java48
-rw-r--r--docs/dist/examples/spacewar/Debug.java219
-rw-r--r--docs/dist/examples/spacewar/Display.java166
-rw-r--r--docs/dist/examples/spacewar/Display1.java203
-rw-r--r--docs/dist/examples/spacewar/Display2.java138
-rw-r--r--docs/dist/examples/spacewar/EnergyPacket.java44
-rw-r--r--docs/dist/examples/spacewar/EnergyPacketProducer.java63
-rw-r--r--docs/dist/examples/spacewar/EnsureShipIsAlive.java35
-rw-r--r--docs/dist/examples/spacewar/Game.java215
-rw-r--r--docs/dist/examples/spacewar/GameSynchronization.java54
-rw-r--r--docs/dist/examples/spacewar/Makefile12
-rw-r--r--docs/dist/examples/spacewar/Pilot.java44
-rw-r--r--docs/dist/examples/spacewar/Player.java122
-rw-r--r--docs/dist/examples/spacewar/README.html79
-rw-r--r--docs/dist/examples/spacewar/Registry.java126
-rw-r--r--docs/dist/examples/spacewar/RegistrySynchronization.java58
-rw-r--r--docs/dist/examples/spacewar/Robot.java201
-rw-r--r--docs/dist/examples/spacewar/SWFrame.java92
-rw-r--r--docs/dist/examples/spacewar/Ship.java296
-rw-r--r--docs/dist/examples/spacewar/SpaceObject.java106
-rw-r--r--docs/dist/examples/spacewar/Timer.java53
-rw-r--r--docs/dist/examples/telecom/AbstractSimulation.java80
-rw-r--r--docs/dist/examples/telecom/BasicSimulation.java34
-rw-r--r--docs/dist/examples/telecom/Billing.java80
-rw-r--r--docs/dist/examples/telecom/BillingSimulation.java44
-rw-r--r--docs/dist/examples/telecom/Call.java97
-rw-r--r--docs/dist/examples/telecom/Connection.java87
-rw-r--r--docs/dist/examples/telecom/Customer.java112
-rw-r--r--docs/dist/examples/telecom/Local.java26
-rw-r--r--docs/dist/examples/telecom/LongDistance.java26
-rw-r--r--docs/dist/examples/telecom/Timer.java50
-rw-r--r--docs/dist/examples/telecom/TimerLog.java29
-rw-r--r--docs/dist/examples/telecom/Timing.java62
-rw-r--r--docs/dist/examples/telecom/TimingSimulation.java40
-rw-r--r--docs/dist/examples/tjp/Demo.java40
-rw-r--r--docs/dist/examples/tjp/GetInfo.java49
-rw-r--r--docs/dist/examples/tracing/Circle.java71
-rw-r--r--docs/dist/examples/tracing/ExampleMain.java44
-rw-r--r--docs/dist/examples/tracing/README32
-rw-r--r--docs/dist/examples/tracing/Square.java71
-rw-r--r--docs/dist/examples/tracing/TwoDShape.java78
-rw-r--r--docs/dist/examples/tracing/lib/AbstractTrace.java185
-rw-r--r--docs/dist/examples/tracing/lib/TraceMyClasses.java67
-rw-r--r--docs/dist/examples/tracing/version1/Trace.java83
-rw-r--r--docs/dist/examples/tracing/version1/TraceMyClasses.java75
-rw-r--r--docs/dist/examples/tracing/version2/Trace.java123
-rw-r--r--docs/dist/examples/tracing/version2/TraceMyClasses.java43
-rw-r--r--docs/dist/examples/tracing/version3/Trace.java123
-rw-r--r--docs/dist/examples/tracing/version3/TraceMyClasses.java46
-rw-r--r--docs/faq/faq.xml3397
-rw-r--r--docs/install/finish.html20
-rw-r--r--docs/install/install-finish.html20
-rw-r--r--docs/install/install-start.html21
-rw-r--r--docs/install/intro.html24
-rw-r--r--docs/install/location.html23
-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
-rw-r--r--docs/readme-docs-module.html32
128 files changed, 25830 insertions, 0 deletions
diff --git a/docs/build.xml b/docs/build.xml
new file mode 100644
index 000000000..30b281cf9
--- /dev/null
+++ b/docs/build.xml
@@ -0,0 +1,399 @@
+<!-- -*- Mode: SGML; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -->
+<!-- ========================================================================= -->
+<!-- Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). -->
+<!-- All rights reserved. -->
+<!-- This program and the accompanying materials are made available -->
+<!-- under the terms of the Common Public License v1.0 -->
+<!-- which accompanies this distribution and is available at -->
+<!-- http://www.eclipse.org/legal/cpl-v10.html -->
+<!-- -->
+<!-- Contributors: -->
+<!-- Xerox/PARC initial implementation -->
+<!-- ========================================================================= -->
+
+<!--
+
+Using this:
+ - default target (dist) creates deployment-like dir in build output dir
+ - target download.files deploys locally and creates installers
+ - individual targets build pieces (api, etc.)
+ - clean only cleans the build directory
+
+Understanding this:
+
+ The documentation output structure is (ignoring alpha order):
+
+ aspectj/
+ README-DOC.html
+ style.css
+ examples/
+ doc/
+ index.html
+ changes.html
+ porting.html
+ oldversions/
+ faq.html
+ quickref.html
+
+ devguide.pdf
+ progguide.pdf
+ quickref.pdf
+
+ api/
+ progguide/
+ devguide/
+
+ The input structure is
+
+ aspectj/
+ README-DOC.html
+ style.css
+ examples/
+ doc/
+ index.html
+ changes.html
+ porting.html
+ oldversions/
+ faq/faq.html
+
+ devGuideDB/ to devguide/ devguide.pdf
+ progGuideDB/ to progguide/ progguide.pdf
+ ?? to quickref.pdf quickref.html
+ src/org/aspectj/lang/*.java | to api
+ src/org/aspectj/lang/reflect/*.java |
+
+data flow and operations (in terms of script names):
+ - input - - target - - output -
+ ${docs.src.dir} dist ${docs.dist.dir}
+ ${docs.src.dir} api ${docs.dist.dir}
+ ${docs.src.dir} faq ${docs.dist.dir}
+ ${docs.src.dir} examples ${docs.dist.dir}
+ ${docs.src.dir} devguide ${docs.dist.dir}
+ ${docs.src.dir} progguide ${docs.dist.dir}
+ ${docs.src.dir} allTheRest ${docs.dist.dir}
+ ${docs.dist.dir} web.deploy ${web.doc.dir}
+ ${aj.release.dir}/.. download.push (ajpush)
+
+XXX no update to avoid builds in this script
+ -->
+
+<!DOCTYPE project [
+<!ENTITY build-properties SYSTEM "file:../build/build-properties.xml">
+]>
+<project name="build-docs" default="dist" basedir=".">
+ <!-- todo: download.files requires build-installer -->
+ <property name="project.name" value="build-docs"/>
+
+ <target name="quicklook" depends="dist"/>
+ <target name="product" depends="local-dist"/>
+ <target name="download.files" depends="dist"/>
+ <target name="clean"
+ depends="clean-directories,clean-doc-directories"/>
+
+ <!-- ===================================================================== -->
+ <!-- Init -->
+ <!-- ===================================================================== -->
+
+ &build-properties;
+
+ <target name="init" depends="init-properties,init-directories">
+
+ <property name="docs.src.dir"
+ location="${aspectj.modules.docs.dir}"/>
+
+ <property name="docs.dist.dir" location="${aj.dist.dir}/docs"/>
+ <property name="docs.temp.dir" location="${aj.temp.dir}/doc"/>
+ <property name="web.doc.dir" location="${aj.webDeploy.dir}/documentation/dist"/>
+
+ <property name="docs.product.name"
+ value="aspectj-docs-${build.version}"/>
+
+ <property name="docs.product.zip"
+ location="${aj.dist.dir}/${docs.product.name}.zip"/>
+ <!-- must specify (not *.gif) to not delete other gifs during build-in-place -->
+ <!-- to find refs: gp ax imagedata | sed -n 's|.*\=\"\(..*\)\".*|\1|p' -->
+ <property name="devguide.icons.dir"
+ location="${aspectj.modules.dir}/ajde/src/org/aspectj/ajde/resources/actions"/>
+ <property name="include.devguide.icons"
+ value="startAjde.gif,build.gif,openConfig.gif,browseroptions.gif,jbuilder-build.gif" />
+
+ <!-- callers of xml-html use these by default -->
+ <property name="chunk.xsl.source"
+ location="${aspectj.modules.lib.dir}/docbook/docbook-xsl/html/chunk.xsl"/>
+ <property name="nochunk.xsl.source"
+ location="${aspectj.modules.lib.dir}/docbook/docbook-xsl/html/docbook.xsl"/>
+ <!-- default xml-html nochunking file (0-length dummy created when chunking) -->
+ <property name="xml-target-file"
+ location="${docs.temp.dir}/xml-target-file.dummy"/>
+ <!-- default value for xml-html copying (copy all graphics) -->
+ <property name="xml-html-copy" value="*.gif,*.png" />
+
+ <uptodate property="local.dist.uptodate"
+ targetfile="${docs.dist.dir}/faq.html"> <!-- use faq as tag file -->
+ <srcfiles dir="${docs.src.dir}"/>
+ </uptodate>
+
+ <uptodate property="dist.uptodate"
+ targetfile="${docs.product.zip}"> <!-- use zip as tag file -->
+ <srcfiles dir="${docs.src.dir}"/>
+ <srcfiles dir="${docs.dist.dir}"/>
+ </uptodate>
+
+ </target>
+
+ <target name="clean-doc-directories" depends="init"
+ description="clean build dirs (including local deploy dir)">
+ <delete quiet="on">
+ <fileset dir="${docs.dist.dir}" />
+ <fileset dir="${docs.jar.dir}" />
+ <fileset dir="${docs.temp.dir}" />
+ </delete>
+ </target>
+
+ <target name="dist" depends="init,local-dist"
+ description="create doc distribution zip"
+ unless="dist.uptodate">
+ <delete file="${docs.product.zip}"/>
+ <zip zipfile="${docs.product.zip}"
+ basedir="${docs.dist.dir}"/>
+
+ <echo message="find doc zip in ${docs.product.zip}"/>
+ </target>
+
+ <target name="web.deploy.faqonly" depends="init,faq"
+ description="deploy docs.dist.dir faq to web.doc.dir">
+ <copy todir="${web.doc.dir}" filtering="on">
+ <fileset dir="${docs.dist.dir}/doc" includes="faq.html"/>
+ </copy>
+ <stripnonbodyhtml srcdir="${web.doc.dir}"
+ includes="faq.html" />
+ <echo message="do link check on index and faq before release"/>
+ </target>
+
+ <target name="web.deploy.faqindex" depends="init,dist"
+ description="deploy built faq and index to web.doc.dir">
+ <copy todir="${web.doc.dir}" filtering="on">
+ <fileset dir="${docs.dist.dir}/doc"
+ includes="faq.html,index.html"/>
+ </copy>
+ <stripnonbodyhtml srcdir="${web.doc.dir}"
+ includes="faq.html,index.html" />
+ <echo message="do link check on index and faq before release"/>
+ </target>
+
+ <target name="web.deploy" depends="web.deploy.README-11" />
+
+ <target name="web.deploy.README-11" depends="init"
+ description="deploy README-11.html to the web site">
+ <property name="readme11.dir"
+ location="${web.doc.dir}/documentation/readme11"/>
+ <mkdir dir="${readme11.dir}"/>
+ <delete file="${readme11.dir}/index.html"/>
+ <mkdir dir="${readme11.dir}"/>
+ <copy tofile="${readme11.dir}/index.html"
+ file="${aspectj.products.dir}/tools/dist/README-11.html"
+ filtering="on"/>
+ <stripnonbodyhtml srcdir="${readme11.dir}"
+ includes="index.html" />
+ </target>
+
+ <target name="web.deploy.old" depends="init"
+ description="deploy built docs to the web site">
+ <mkdir dir="${web.doc.dir}"/>
+ <delete dir="${web.doc.dir}"/>
+ <mkdir dir="${web.doc.dir}"/>
+ <copy todir="${web.doc.dir}">
+ <fileset dir="${docs.dist.dir}/doc"/>
+ </copy>
+ <stripnonbodyhtml srcdir="${web.doc.dir}"
+ includes="**/*.html" />
+ </target>
+
+ <!-- ============================================================ -->
+ <!-- build all doc products -->
+ <!-- ============================================================ -->
+ <target name="local-dist" depends="init"
+ unless="local.dist.uptodate" >
+ <antcall target="do-local-dist"/>
+ </target>
+ <target name="do-local-dist"
+ depends="init,init-filters,api,faq,devguide,progguide"
+ unless="local.dist.uptodate"
+ description="finish products by copying dist files">
+ <copy todir="${docs.dist.dir}" filtering="on">
+ <fileset dir="${docs.src.dir}/dist" />
+ </copy>
+ </target>
+
+ <target name="api" depends="init"
+ description="javadoc for AspectJ lang and lang.reflect">
+ <delete dir="${docs.dist.dir}/doc/api"/>
+ <mkdir dir="${docs.dist.dir}/doc/api"/>
+ <javadoc sourcepath="${aspectj.modules.dir}/runtime/src"
+ destdir="${docs.dist.dir}/doc/api"
+ windowtitle="AspectJ(tm) runtime API"
+ link="http://java.sun.com/j2se/1.4/docs/api/index.html"
+ packagenames="org.aspectj.lang,org.aspectj.lang.reflect" />
+ <!-- note: link ineffective at avoiding see tag warning -->
+ </target>
+
+ <target name="faq" depends="init">
+ <antcall target="xml-html">
+ <param name="xml-source-dir"
+ value="${docs.src.dir}/faq"/>
+ <param name="xml-source-root"
+ value="faq.xml"/>
+ <param name="xsl-source-file"
+ value="${nochunk.xsl.source}"/>
+ <param name="xml-target-dir"
+ value="${docs.dist.dir}"/>
+ <param name="xml-target-file"
+ value="${docs.dist.dir}/doc/faq.html"/>
+ </antcall>
+ </target>
+
+ <!-- experimental targets collapse guide-making (lose individual targets) -->
+ <target name="progguide" depends="init">
+ <antcall target="build-guide">
+ <param name="guide.dir" value="progGuideDB"/>
+ <param name="guide.name" value="progguide"/>
+ </antcall>
+ </target>
+
+ <target name="devguide" depends="init">
+ <copy todir="${docs.src.dir}/devGuideDB" filtering="off" >
+ <fileset dir="${aspectj.modules.dir}/ajde/src/org/aspectj/ajde/resources/actions"
+ includes="${include.devguide.icons}" />
+ </copy>
+ <antcall target="build-guide">
+ <param name="guide.dir" value="devGuideDB"/>
+ <param name="guide.name" value="devguide"/>
+ </antcall>
+ <delete quiet="on"> <!-- clean icons for build-in-place -->
+ <fileset dir="${docs.src.dir}/devGuideDB"
+ includes="${include.devguide.icons}" />
+ </delete>
+ </target>
+
+ <target name="build-guide" depends="init"
+ description="build prog or dev guide, using guide.dir and guide.name">
+ <!-- chunked -->
+ <antcall target="xml-html">
+ <param name="xml-source-dir"
+ value="${docs.src.dir}/${guide.dir}"/>
+ <param name="xml-source-root"
+ value="${guide.name}.xml"/>
+ <param name="xsl-source-file"
+ value="${chunk.xsl.source}"/>
+ <param name="xml-target-dir"
+ value="${docs.dist.dir}/doc/${guide.name}"/>
+ </antcall>
+ <!-- single -->
+ <antcall target="xml-html">
+ <param name="xml-source-dir"
+ value="${docs.src.dir}/${guide.dir}"/>
+ <param name="xml-source-root"
+ value="${guide.name}.xml"/>
+ <param name="xsl-source-file"
+ value="${nochunk.xsl.source}"/>
+ <param name="xml-target-dir"
+ value="${docs.dist.dir}/doc/${guide.name}"/>
+ <param name="xml-target-file"
+ value="${docs.dist.dir}/doc/${guide.name}/printable.html"/>
+ </antcall>
+ <!-- pdf - enable when it works
+ <antcall target="xml-pdf">
+ <param name="xml-source-dir"
+ value="${docs.src.dir}/doc/${guide.dir}"/>
+ <param name="xml-source-root" value="${guide.name}.xml"/>
+ <param name="xml-target-file"
+ value="${docs.dist.dir}/doc/${guide.name}.pdf"/>
+ </antcall>
+ -->
+ </target>
+ <!-- end of experimental targets -->
+
+ <!-- XML conversion stuff -->
+
+ <!-- todo xml-pdf broken; when fixed, see xml-html for example -->
+ <target name="xml-pdf">
+ <delete file="${xml-target-file}"/>
+ <touch file="${xml-target-file}"/>
+ <java classname="com.icl.saxon.StyleSheet"
+ fork="yes">
+ <classpath>
+ <pathelement location="${saxon.dir}/saxon.jar"/>
+ </classpath>
+ <arg value="-o"/>
+ <arg value="${xml-source-dir}/index.fo"/>
+ <arg value="${xml-source-dir}/${xml-source-root}"/>
+ <arg value="${docbook.dir}/docbook-xsl/fo/docbook.xsl"/>
+ </java>
+ </target>
+
+ <target name="xml-html"
+ description="antcall(xml-source-dir, xml-source-root, xml-target-dir, xml-target-file)
+ convert xml to html using docbook. parameters:
+ xml-source-dir # base directory of source
+ xml-source-root # base file of source (relative to xml-source-dir)
+ xsl-source-file # xsl transform to apply (use chunk.xsl.source by default)
+ xml-target-dir # target directory for output (used as xsl param base.dir)
+ xml-target-file # full path to output file in xml-source-dir, ignored when chunking
+ xml-html-copy # copy files to target (defaults to *.gif,*.png">
+
+ <mkdir dir="${xml-target-dir}"/>
+ <copy todir="${xml-target-dir}">
+ <fileset dir="${xml-source-dir}"
+ includes="${xml-html-copy}"/>
+ </copy>
+ <java classname="com.icl.saxon.StyleSheet"
+ classpath="${aspectj.modules.lib.dir}/saxon/saxon.jar"
+ fork="yes"
+ failonerror="yes"> <!-- todo: establish failure policy -->
+ <arg value="-o"/>
+ <arg value="${xml-target-file}"/>
+ <arg value="${xml-source-dir}/${xml-source-root}"/>
+ <arg value="${xsl-source-file}"/>
+ <arg value="base.dir=${xml-target-dir}/"/>
+ </java>
+ </target>
+
+ <target name="info"
+ description="misc info for writing and building docbook">
+<echo>
+---- misc info for writing and building docbook
+- link tag linkend attribute takes an id
+ - xsl converts as needed during output
+ - do NOT use ulink; this will be converted to ""
+ (but see param citerefentry-link: might enable this)
+
+- to use sensible names for the files produced,
+ - use an xsl wrapper to add/modify features
+ - set flag to use the id of the top-level element in the output
+ file as the filename.
+ xsl:param name="use.id.as.filename" select="1"
+ - fyi, other related parameters: html-ext, root-filename
+ - In this example, the top-level element in the output file
+ is the refentry, so set ids which become the basename of the file:
+ refentry id="aspectj-mode" # in aspectj-mode.xml, produces aspecj-mode.html
+ refentry id="ajdee" # in ajdee.xml, produces ajdee.html
+
+-- fyi
+- related parameters:
+ html-ext, root-filename
+- these tags did not work for me:
+ dbhtml filename="foo.htm"
+ dbhtml prefix="foo-"
+
+- resources
+ - the dtd reference for docbook
+ http://www.oreilly.com/catalog/docbook/chapter/book/docbook.html
+ - the stylesheet reference for docbook xsl
+ http://docbook.sourceforge.net/projects/dsssl/doc/html.html
+- todo
+ - fyi, generate.reference.titlepage appears not to be respected.
+ tried to add if statement to html/refentry.xsl, but file still gen'd
+</echo>
+ </target>
+
+</project>
diff --git a/docs/devGuideDB/ajbrowser-building.gif b/docs/devGuideDB/ajbrowser-building.gif
new file mode 100644
index 000000000..29767c605
--- /dev/null
+++ b/docs/devGuideDB/ajbrowser-building.gif
Binary files differ
diff --git a/docs/devGuideDB/ajbrowser-options.gif b/docs/devGuideDB/ajbrowser-options.gif
new file mode 100644
index 000000000..41ba67654
--- /dev/null
+++ b/docs/devGuideDB/ajbrowser-options.gif
Binary files differ
diff --git a/docs/devGuideDB/ajbrowser.xml b/docs/devGuideDB/ajbrowser.xml
new file mode 100644
index 000000000..f4a44597c
--- /dev/null
+++ b/docs/devGuideDB/ajbrowser.xml
@@ -0,0 +1,222 @@
+<refentry>
+ <refnamediv>
+ <refname>AspectJ Browser</refname>
+
+ <refpurpose>GUI tool for compiling programs with ajc and navigating the
+ crosscutting structure (early-access)</refpurpose>
+
+ </refnamediv>
+
+ <refsect1 id="ajbrowser" xreflabel="AspectJ Browser">
+ <title>Overview</title>
+
+
+ <para>
+ The AspectJ Browser is a development tool that will allow you to
+ compile using ajc, navigate your program's static structure, edit
+ source files, and graphically edit build configuration files.
+ </para>
+
+ <imageobject>
+ <imagedata fileref="ajbrowser-building.gif"/>
+ </imageobject>
+
+ <para>
+ To use the browser launch it by typing "ajbrowser" (assuming that
+ you've followed the instructions for setting up <xref
+ linkend="ajc">ajc</xref>). You can either pass in one or more
+ ".lst" build configuration files as command line parameters to the
+ browser in order to build them and navigate the corresponding
+ structure, or you can open one or more ".lst" files with "File ->
+ Open" or with the "Open Build Configuration" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="openConfig.gif"/>
+ </imageobject>
+ </inlinemediaobject>).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Compiling a Build Configuration</title>
+
+ <para>
+ To compile click the "Build" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="build.gif"/>
+ </imageobject>
+ </inlinemediaobject>), or click &lt;ctrl&gt;F11. You may also select a
+ different build configuration here, as in label 1.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Navigating the Program Structure</title>
+
+ <para>
+ Select nodes in the program structure by clicking them (as in label 2).
+ If one node is related to one or more other nodes by an association the
+ name of the association will appear below that node and will be
+ displayed in italics. Links to other structure nodes appear in blue
+ below the association. If there is no corresponding source for the
+ link it will appear light-blue.
+ </para>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Manipulating Build Configuration</title>
+
+ <para>
+ Build configurations can be manipulated adding, removing, and
+ editing build configuration files using the corresponding toolbar
+ buttons. The current configuration can be selected in the
+ configurations listbox. Build configurations are represented by
+ ".lst" files (which are described in the <xref
+ linkend="ajc">ajc</xref> documentation).
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Example: Exploring the "Spacewar" sample code </title>
+ <para>
+ <itemizedlist>
+
+ <listitem> <para>Launch <literal>ajbrowser</literal></para>
+ </listitem>
+
+ <listitem> Choose "File -&gt; Open" or click the "Open Build
+ Configuration" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="openConfig.gif"/>
+ </imageobject>
+ </inlinemediaobject>) and select the configuration file for debugging
+ the spacewar example, in
+ <literal>examples/spacewar/debug.lst</literal>.
+ </listitem>
+
+ <listitem> <para>Click the "Build" button (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="build.gif"/>
+ </imageobject>
+ </inlinemediaobject>) to
+ compile. The left pane should fill with a spacewar declaration
+ tree. If there is a compiler error, the clickable error message
+ shows up as in label 4.
+ </para>
+
+ <para>Note: If you did not install in the default location, the
+ compile will fail with a message that you need to install
+ aspectjrt.jar on your compile classpath. To do that, select "Tools
+ -&gt; Options" or click the "Options" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="browseroptions.gif"/>
+ </imageobject>
+ </inlinemediaobject>). Click the <literal>Build Options</literal> tab
+ to view the Build Paths pane. Edit the classpath entry to use your
+ install location, ok the dialog, and retry the compile.
+
+ </para>
+
+ <imageobject>
+ <imagedata fileref="ajbrowser-options.gif"/>
+ </imageobject>
+
+ </listitem>
+
+ <listitem> <para>Different structure views: The structure tree at the
+ left can display different orderings and granularity for structure:
+
+ <itemizedlist>
+ <listitem> The package hierarchy view shows the traditional hierarchy
+ of package, class, and members. </listitem>
+
+ <listitem> The inheritance view shows the hierarchy from topmost
+ parent classes through subclasses to members. </listitem>
+
+ <listitem> The crosscutting view shows the aspect members
+ and the code they affect. </listitem>
+
+ <listitem> Additional buttons in the pane can be used to change the
+ granularity and filter out items.
+ </listitem>
+
+ </itemizedlist>
+
+ </para>
+
+ <para>Whenever you select an item in the tree view, the
+ source pane scrolls to that item. If you select a leaf item
+ representing another program element, then the tree
+ selection will go to the corresponding node. (See below for
+ how to use two panes to maintain your place.)
+ </para>
+
+ </listitem>
+ <listitem>
+
+ <para>When working with aspects, it helps to be able to navigate
+ between different program elements:
+ </para>
+
+ <itemizedlist>
+
+ <listitem><para>When looking at a method, find the advice that
+ affects it. </para></listitem>
+
+ <listitem><para>When looking at a pointcut, find the advice that
+ uses it. </para></listitem>
+
+ <listitem><para>When looking at advice, find what it advises -
+ e.g., method calls or executions, initializers, etc.
+ </para></listitem>
+
+ <listitem><para>When looking at a type, find any aspects that
+ declare members or supertypes of the type, or
+ vice-versa.
+ </para></listitem>
+
+ </itemizedlist>
+
+ <para>You can view the advice on a particular method using the
+ default, hierarchical view. Navigate to the tree item for
+ <literal>spacewar.Registry.register(SpaceObject)</literal>
+ in the <literal>debug.lst</literal> config file. Now, in
+ the lower, file view, you can see and navigate to the advice
+ using the subtree whose parent is the <literal>method
+ affected by</literal> relation.
+ </para>
+
+ <para>You can also use crosscutting view to see the
+ advice using a pointcut or the methods affected by advice.
+ For example, to see what advice uses a particular pointcut,
+ navigate to the tree item for the pointcut
+ <literal>spacewar.Debug.allConstructorsCut()</literal> in
+ the <literal>debug.lst</literal> config file. You can see
+ and navigate to the advice that uses the pointcut using the
+ <literal>pointcut used by</literal> relation.
+ </para>
+
+ <para>As an example of seeing the methods affected by advice,
+ while still in the same view, select the first
+ <literal>before</literal> advice in
+ <literal>spacewar.Debug</literal>. It has relation
+ sub-trees for both <literal>uses pointcut</literal> and
+ <literal>affects constructions</literal>. The
+ <literal>affects</literal> relations will list different
+ kinds of join points - constructor or method calls, etc.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajc.xml b/docs/devGuideDB/ajc.xml
new file mode 100644
index 000000000..28347b90b
--- /dev/null
+++ b/docs/devGuideDB/ajc.xml
@@ -0,0 +1,484 @@
+<refentry>
+ <refnamediv>
+ <refname>ajc</refname>
+ <refpurpose>compiler for the AspectJ language </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ajc</command>
+ <arg><replaceable>Options</replaceable></arg>
+ <group>
+ <arg><replaceable>file...</replaceable></arg>
+ <arg>@<replaceable>file...</replaceable></arg>
+ <arg>-argfile <replaceable>file...</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="ajc" xreflabel="ajc">
+ <title>Description</title>
+
+ <para>The command <command>ajc</command> compiles AspectJ and Java
+ language source files into class files. Options and files may be
+ specified directly on the command line, or indirectly by naming a
+ file which contains them.</para>
+
+ <para> The arguments after the options specify the file(s) to compile.
+ Files may be listed directly on the command line, or listed in a file.
+ The <parameter>@<replaceable>file</replaceable></parameter> and
+ <parameter>-argfile <replaceable>file</replaceable></parameter> forms
+ are equivalent, and are interpreted as meaning all the files listed in
+ the specified file. Each line in these files should contain one option
+ or filename. Comments, as in Java, start with <literal>//</literal> and
+ extend to the end of the line.
+ </para>
+
+ <para>
+ <command>NB:</command> You must explicitly pass ajc all of the source files necessary
+ for the compilation. When you are compiling source files containing aspects
+ or pointcuts, be sure
+ to include the source files for any types affected by the aspects or
+ picked out by the pointcuts.
+ (If you wish to exclude types from the scope affected by the
+ aspect, change the corresponding pointcut or declaration.)
+ This is necessary because, unlike javac, ajc does not search the sourcepath for classes.
+ </para>
+
+ <refsect2>
+ <title>Options</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>-verbose</term>
+ <listitem><para>
+ Output messages about what ajc is doing
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-version</term>
+ <listitem><para>
+ Print the version of ajc
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-nocomments</term>
+ <listitem><para>
+ Don't generate any comments into the woven code.
+ Only relevant with -preprocess mode.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-emacssym</term>
+ <listitem><para>
+ Generate symbols used by AJDE for Emacs
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-usejavac</term>
+ <listitem><para>
+ Use javac to generate .class files
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-preprocess</term>
+ <listitem><para>
+ Don't try to generate any .class files.
+ Generate regular Java code into <replaceable>workingdir</replaceable>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-workingdir <replaceable>Directory</replaceable></term>
+ <listitem><para>
+ Specify where to place intermediate .java files
+ <replaceable>Directory</replaceable> defaults to ./ajworkingdir.
+ Only relevant with -usejavac or -preprocess modes.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term></term>
+ <listitem><para>
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term></term>
+ <listitem><para>
+
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-O</term>
+ <listitem><para>
+ Optimize; may hinder debugging or enlarge class files
+ </para></listitem>
+ </varlistentry>
+
+ <!-- We don't actually warn about deprecated methods ever
+ <varlistentry>
+ <term>-deprecation</term>
+ <listitem><para>
+ Output source locations where deprecated APIs are used
+ </para></listitem>
+ </varlistentry>
+ -->
+
+ <varlistentry>
+ <term>-d <replaceable>Directory</replaceable></term>
+ <listitem><para>
+ Specify where to place generated .class files
+ <replaceable>Directory</replaceable> defaults to the current working dir
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term></term>
+ <listitem><para>
+
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-classpath <replaceable>Path</replaceable></term>
+ <listitem><para>
+ Specify where to find user class files
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-bootclasspath <replaceable>Path</replaceable></term>
+ <listitem><para>
+ Override location of bootstrap class files
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-extdirs <replaceable>Path</replaceable></term>
+ <listitem><para>
+ Override location of installed extensions
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-argfile <replaceable>File</replaceable></term>
+ <listitem><para>
+ the file is a line-delimited list of arguments
+ these arguments are inserted into the argument list
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-encoding <replaceable>Encoding</replaceable></term>
+ <listitem><para>
+ Specify character encoding used by source files
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-source <replaceable>1.4</replaceable></term>
+ <listitem><para>
+ Specify support for assertions according to the 1.4 Java language.
+ This will treat <literal>assert</literal> as a keyword and will
+ implement assertions according to the 1.4 language spec.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-lenient</term>
+ <listitem><para>
+ Be extra-lenient in interpreting the java specification
+ This allows some statements that some compilers consider errors.
+ </para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>-strict</term>
+ <listitem><para>
+ Be extra-strict in interpreting the java specification
+ This signals errors for some statements that many compilers don't
+ catch, and generates code strictly according to the Java Language
+ Specification, even though such code may not run on 1.2 VMs.
+ </para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ </refsect2>
+
+ <refsect2> <title>File names</title>
+
+ <para>ajc accepts source files with either the <filename>.java</filename>
+ extension or the <filename>.aj</filename> extension. We normally use
+ <filename>.java</filename> for all of our files in an AspectJ system -- files
+ that contain aspects as well as files that contain classes. However, if
+ you have a need to mechanically distinguish files that use AspectJ's
+ additional functionality from those that are pure Java we recommend using
+ the <filename>.aj</filename> extension for those files.</para>
+
+ <para>We'd like to discourage other means of mechanical distinction such as
+ naming conventions or sub-packages in favor of the <filename>.aj</filename>
+ extension.</para>
+
+ <itemizedlist>
+
+ <listitem>Filename conventions are hard to enforce and lead to awkward names
+ for your aspects. Instead of <filename>TracingAspect.java</filename> we
+ recommend using <filename>Tracing.aj</filename> (or just
+ <filename>Tracing.java</filename>) instead.</listitem>
+
+ <listitem>Sub-packages move aspects out of their natural place in a system
+ and can create an artificial need for privileged aspects. Instead of
+ adding a sub-package like <filename>aspects</filename> we recommend using the
+ <filename>.aj</filename> extension and including these files in your existing
+ packages instead.</listitem>
+
+ </itemizedlist>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Compatibility</title>
+
+ <para>
+ AspectJ is a compatible extension to the Java programming language. The
+ AspectJ compiler adheres to the <ulink
+ url="http://java.sun.com/docs/books/jls/index.html"> <citetitle
+ pubwork="book">The Java Language Specfication, Second
+ Edition</citetitle></ulink> and to the <ulink
+ url="http://java.sun.com/docs/books/vmspec/index.html"><citetitle
+ pubwork="book">The Java Virtual Machine Specification, Second
+ Edition</citetitle></ulink> and runs on any Java 2 compatible
+ platform. The code it generates runs on any Java 1.1 or later
+ compatible platform.</para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Examples</title>
+
+ <example id="simpleexample">
+ <title>A simple example</title>
+
+ <para>Compile two files:</para>
+
+ <programlisting>
+ ajc HelloWorld.java Trace.java
+ </programlisting>
+
+ </example>
+
+ <example id="exampleusingargfile">
+ <title>An example using -argfile/@</title>
+
+ <para>
+ To avoid specifying file names on the command line,
+ list source files in a line-delimited text argfile.
+ Source file paths may be absolute or relative to the argfile,
+ and may include other argfiles by @-reference.
+ The following file <literal>sources.lst</literal>
+ contains absolute and relative files and @-references:
+ <para><programlisting>
+Gui.java
+/home/user/src/Library.java
+data/Repository.java
+data/Access.java
+@../../common/common.lst
+@/home/user/src/lib.lst
+view/body/ArrayView.java</programlisting></para>
+
+ Compile the files using either the -argfile or @ form:
+
+ <para><programlisting>
+ajc -argfile sources.lst
+ajc @sources.lst</programlisting></para>
+ </para>
+ <para>
+ Argfiles are also supported by jikes, javac, and ajdoc, so you
+ can use the files in hybrid builds. However, the support varies:
+ </para>
+
+ <simplelist>
+ <listitem>Only ajc accepts command-line options</listitem>
+ <listitem>Jikes and Javac do not accept internal @argfile references.
+ </listitem>
+ <listitem>Jikes and Javac only accept the @file form on the command line.</listitem>
+ </simplelist>
+
+ </example>
+
+ <!-- these examples suck
+ <example id="mixingoptionsandfiles">
+ <title>Mixing directly and indirectly specified options and
+ files</title>
+
+ <para>Invoke the AspectJ compiler with the options <literal>-threads
+ 2</literal>, <literal>-deprecation</literal>,
+ <literal>-verbose</literal> and the options listed in the file
+ <filename>standard_ajc_options</filename> on the files listed in
+ <filename>prog_src_files</filename>. </para>
+
+ <programlisting>
+ ajc -threads 2 -deprecation @standard_ajc_options -argfile prog_src_files -verbose
+ </programlisting>
+
+ </example>
+
+ <example id="optionsnotinajc">
+
+ <title>Compiling with options not directly supported by
+ <command>ajc</command></title>
+
+ <para>Run the AspectJ compiler on the file
+ <filename>figures/FigureElement.java</filename> but do not generate
+ <filename>.class</filename> (bytecode) files. Keep the generated
+ Java source files and place them in the directory
+ <filename>tmp</filename>.</para>
+
+<programlisting>
+ ajc -preprocess -workingdir tmp figures/FigureElement.java
+</programlisting>
+
+ <para>You may then compile those files with:</para>
+
+ <programlisting>
+ cd tmp
+ javac -g figures/FigureElement.java
+ </programlisting>
+
+ </example>
+
+ <example id="usingjikes">
+ <title>Using <command>jikes</command></title>
+
+ <para>Invoke the AspectJ compiler on the file
+ <filename>figures/FigureElement.java</filename>, saving the
+ generated Java files in the directory
+ <filename>ajworkingdir</filename>. Then invoke the Jikes compiler
+ on the generated Java files.</para>
+
+ <programlisting>
+ JIKESPATH=$JAVA_HOME/jre/lib/rt.jar:$CLASSPATH
+ ajc -preprocess figures/FigureElement.java
+ cd ajworkingdir
+ jikes figures/FigureElement.java
+ </programlisting>
+
+ <para>Since <command>jikes</command> cannot infer the location of the
+ standard class files the way <command>javac</command> can, you must
+ tell it explicitly how to find the system and user class files it
+ needs. You may either use the <literal>-classpath</literal> option to
+ both <command>ajc</command> and to <command>jikes</command>, or you
+ may define the enviroment variables <envar>CLASSPATH</envar> and
+ <envar>JIKESPATH</envar> appropriately.</para>
+
+ </example>
+ -->
+
+ </refsect2>
+
+ <refsect2>
+ <title>The AspectJ compiler API</title>
+
+ <para>The AspectJ compiler is implemented completely in Java and can be
+ called as a Java class. The only interface that should be considered
+ public is the method <literal>org.aspectj.tools.ajc.Main.main(String[]
+ args)</literal>
+ where <literal>args</literal> are the standard <command>ajc</command>
+ command line arguments. This means that an alternative way to run the
+ compiler is </para>
+
+ <cmdsynopsis>
+ <command><literal>java org.aspectj.tools.ajc.Main</literal></command>
+ <arg><replaceable>option...</replaceable></arg>
+ <arg><replaceable>file...</replaceable></arg>
+ </cmdsynopsis>
+
+<!-- <note> -->
+ <para>
+ To run in <literal>-usejavac</literal> mode,
+ you must include in your classpath the
+ <filename>tools.jar</filename> from your Java 2 developer's kit.
+ </para>
+<!-- </note> -->
+ </refsect2>
+
+ <refsect2>
+ <title>Stack Traces and the SourceFile attribute</title>
+
+ <para>Unlike traditional java compilers, the AspectJ compiler may in
+ certain cases generate classfiles from multiple source files.
+ Unfortunately, the Java class file format does not support multiple
+ SourceFile attributes. So, in order to make sure all source file
+ information is available, the AspectJ compiler may in some cases
+ encode multiple filenames in the SourceFile attribute.
+ </para>
+
+ <para>Probably the only time you may see this format is when you view
+ stack traces, where you may encounter traces of the format
+ </para>
+
+<programlisting>
+java.lang.NullPointerException
+ at Main.new$constructor_call37(Main.java;SynchAspect.java[1k]:1030)
+</programlisting>
+
+ <para>where instead of the usual
+ </para>
+
+<programlisting>
+File:LineNumber
+</programlisting>
+
+ <para>format, you see
+ </para>
+
+<programlisting>
+File0;File1[Number1];File2[Number2] ... :LineNumber
+</programlisting>
+
+ <para>In this case, LineNumber is the usual offset in lines plus the
+ "start line" of the actual source file. That means you use LineNumber
+ both to identify the source file and to find the line at issue.
+ The number in [brackets] after each file tells you the
+ virtual "start line" for that file (the first file has a start of 0).
+ </para>
+
+ <para> In our example from the null pointer exception trace,
+ the virtual start line is 1030. Since the file SynchAspect.java
+ "starts" at line 1000 [1k], the LineNumber points to line 30 of
+ SynchAspect.java.
+ </para>
+
+ <para> So, when faced with such stack traces, the way to find the actual
+ source location is to look through the list of "start line" numbers to
+ find the one just under the shown line number. That is the file where
+ the source location can actually be found. Then, subtract that "start
+ line" from the shown line number to find the actual line number within
+ that file.
+ </para>
+
+ <para>Of course, AspectJ tools will do this decoding for you, and in a
+ class file that comes from only a single source file, the AspectJ
+ compiler generates SourceFile attributes consistent with
+ traditional Java compilers.
+ </para>
+
+ </refsect2>
+
+
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajdb.xml b/docs/devGuideDB/ajdb.xml
new file mode 100644
index 000000000..832002823
--- /dev/null
+++ b/docs/devGuideDB/ajdb.xml
@@ -0,0 +1,312 @@
+<refentry>
+ <refnamediv>
+ <refname>ajdb</refname>
+ <refpurpose>debugger for .class files produced by ajc (early-access)</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ajdb</command>
+ <arg>-classpath <replaceable>path</replaceable></arg>
+ <arg>-D<replaceable>name</replaceable>=<replaceable>value</replaceable></arg>
+ <arg>-help</arg>
+ <arg>-gui</arg>
+ <arg>-read <replaceable>file</replaceable></arg>
+ <arg>-sourcepath <replaceable>dir</replaceable></arg>
+ <arg>
+ <group>
+ <arg>-v</arg>
+ <arg>-verbose</arg>
+ <group>
+ <arg>:class</arg>
+ <arg>:gc</arg>
+ <arg>:jni</arg>
+ </group>
+ </group>
+ </arg>
+ <arg>workingdir <replaceable>dir</replaceable></arg>
+ <arg>-X<replaceable>option</replaceable></arg>
+ <arg><replaceable>class</replaceable></arg>
+ <arg><replaceable>arguments</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+
+ <para>The command <command>ajdb</command> is used to debug AspectJ and
+ Java programs. In addition to its command line interface,
+ <command>adjb</command> also has a standalone, Swing-based GUI
+ interface.
+ </para>
+ <para>
+ Note: As of the 1.0.3 release, AspectJ supports JSR-45, which provides
+ source-level debugging from many source files per class
+ and non-Java source files.
+ JSR-45 is implemented in the J2SE 1.4 debugger support, so
+ you may be able to use your existing debugger to step through
+ AspectJ source code if both the source and target VM's are
+ running under Java 1.4 or later.
+ However, existing debuggers will display synthetic methods
+ in the stack frame.
+ </para> <!-- todo find docs on JSR-45 -->
+
+ <simplelist>
+ <member>-classpath <emphasis>path</emphasis></member>
+ <member>Specify where to find user class files.</member>
+
+ <member>
+ -D<replaceable>name</replaceable>=<replaceable>value</replaceable>
+ </member>
+ <member>Define the property <literal>name</literal> to have the value
+ <literal>value</literal>.</member>
+
+ <member>-help</member>
+ <member>Print out <command>ajdb</command>'s usage summary.</member>
+
+ <member>-read <emphasis>file</emphasis></member>
+ <member>Read this file for initializatoin commands.</member>
+
+ <member>-sourcepath <emphasis>path</emphasis></member>
+ <member>Search this directory for source files.</member>
+
+ <member>-gui</member>
+ <member></member>
+
+ <member>-v | -verbose [:class | :gc | :jni]</member>
+ <member>Print out class loading, garbage collection or dynamic library
+ loading information. Defaults to class loading.
+ </member>
+
+ <member>-workingdir <emphasis>directory</emphasis></member>
+ <member>Set <command>ajdb</command>'s working directory.</member>
+
+ <member>-X<emphasis>option</emphasis></member>
+ <member>Pass a non-standard option to the VM</member>
+ </simplelist>
+
+ <refsect2>
+ <title>Capabilities</title>
+ <para>
+ The AspectJ debugger implements all of <command>jdb</command>'s
+ commands. In addition, the command <literal>workingdir</literal>
+ allow you to set the AspectJ working directory, and the breakpoint
+ command, <literal>stop on</literal>, has been extended to allow the
+ setting of breakpoint on a source file line.
+ </para>
+ </refsect2>
+
+ <refsect2>
+ <title>Examples</title>
+
+ <example id="ajdbcommandline">
+ <title>Command line use</title>
+
+ <para>Suppose you want to debug the file spacewar/Ship.java found in
+ the examples directory. At the command line start up the debugger:
+
+ <computeroutput>
+ ajdb
+ </computeroutput>
+ </para>
+
+
+ <para>
+ The debugger will first look for initialization files in your
+ home or current directory called either
+ <filename>ajdb.ini</filename> or <filename>.ajdbrc</filename> and
+ execute the commands contained in them. A useful command to have
+ in this file is the <literal>source-path</literal> command which
+ tells the debugger where to find source files.
+ </para>
+
+ <para>For this example, we need to set the source path by:
+
+ <userinput>
+ use C:\src
+ </userinput>
+ </para>
+
+ <para>To view the file to debug, type <userinput>list
+ spacewar/Ship.java</userinput> which generates the following
+ output:
+ <programlisting>
+ 209 void fire() {
+ 210 // firing a shot takes energy
+ 211 if (!expendEnergy(BULLET_ENERGY))
+ 212 return;
+ 213
+ 214 //create a bullet object so it doesn't hit the ship that's firing it
+ 215 double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
+ 216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
+ 217
+ 218 // create the actual bullet
+ 219 new Bullet(
+ 220 getGame(),
+ 221 (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
+ 222 (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
+ 223 xV,
+ 224 yV);
+ 225 }
+ </programlisting>
+ </para>
+ <para>This is different from <command>jdb</command> because it allows
+ one to view files before the debugger has started. The
+ <literal>list</literal> command has the following syntax: </para>
+
+ <simplelist>
+ <member><literal>list</literal></member>
+ <member>list the source containing the location at which we are
+ currently stopped (can only be used with a running VM)</member>
+
+ <member><literal>list</literal>
+ <emphasis><literal>source</literal></emphasis></member>
+ <member>list the entire file source</member>
+
+ <member><literal>list</literal> source line</member>
+ <member>list source line line of file source</member>
+
+ <member>
+ list <emphasis><literal>source start-line
+ end-line</literal></emphasis>
+ </member>
+ <member>
+ list the lines from <emphasis>start-line</emphasis> to
+ <emphasis>end-line</emphasis> of file
+ <emphasis>source</emphasis>
+ </member>
+ </simplelist>
+
+ <para>
+ To set a breakpoint in the method <literal>Ship.fire</literal>, we
+ would could type <userinput>stop in spacewar.Ship.fire</userinput>.
+ </para>
+
+ <para>The following message appears notifying the user that the
+ breakpoint has been noted but will not be set until the class has
+ been loaded by the VM: </para>
+ <programlisting>
+ Deferring breakpoint spacewar.Ship.fire()
+ It will be set after the class is loaded.
+ </programlisting>
+
+ <para>
+ To start Spacewar we type <userinput>run spacewar.Game</userinput>.
+ </para>
+
+ <para>
+ When the breakpoint is set, the following message appears:
+ <programlisting>
+ Set deferred breakpoint spacewar.Ship.fire()
+ </programlisting>
+ </para>
+
+ <para> We are notified that we've hit the breakpoint:
+
+ <programlisting>
+ Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=174, bci=0 209 void fire() {
+ </programlisting></para>
+
+ <para>
+ The prompt changes to present the thread that has broken, and we
+ can view the current stack with the <literal>where</literal>
+ command, as follows:
+ <programlisting>
+ Thread-2[1] where
+ [1] fire (spacewar\Ship.java:209)
+ [2] run (spacewar\Robot.java:100)
+ [3] run [class java.lang.Thread]
+ </programlisting>
+ </para>
+
+ <para>
+ Next, to stop on line 216 we
+ type <userinput>stop on spacewar/Ship.java:216</userinput>
+ </para>
+
+ <para>
+ The following message tells us the breakpoint was set:
+ <programlisting>
+ Set breakpoint Ship.java:216
+ </programlisting>
+ </para>
+ <para>
+ To continue execution, we type <userinput>cont</userinput> and the
+ breakpoint at line 216 is hit
+ <programlisting>
+ Breakpoint hit: thread="Thread-2", spacewar.Ship.fire(), line=216, bci=28
+ 216 double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
+ </programlisting></para>
+
+ <para>
+ To view the visible local variables, we type
+ <userinput>locals</userinput> and ajdb responds with:
+ <programlisting>
+ Local variables
+ xV = 12.242462584304468
+ </programlisting></para>
+
+ <para>
+ To change the value of the local variable i to 15, we type
+ <userinput>set xV = 16.1</userinput>
+
+ <programlisting>
+ Changed 'xV' from '12.242462584304468' to '16.1'
+ </programlisting></para>
+
+ <para>
+ To see our changes we can print the value of <literal>i</literal>
+ by the following:
+ <programlisting>
+ print xV
+ Value for printing 'xV' = 12.242462584304468
+ </programlisting></para>
+
+ <para>We can now type exit or quit to leave the debugger, and we
+ receive the following message:
+
+ <programlisting>
+ The application has exited.
+ </programlisting></para>
+ </example>
+
+ </refsect2>
+
+ <refsect2>
+ <title>The AspectJ debugger API</title>
+
+ <para>
+ The AspectJ debugger is implemented completely in Java and can be
+ called as a Java class. The only interface that should be
+ considered public is the method
+ <literal>org.aspectj.tools.debugger.Main.main(String[]
+ args)</literal> where <literal>args</literal> are the standard
+ <command>ajc</command> command line arguments. This means that an
+ alternative way to run the compiler is </para>
+
+ <cmdsynopsis>
+ <command>
+ <literal>java org.aspectj.tools.debugger.Main</literal>
+ </command>
+ <arg><replaceable>option</replaceable></arg>
+ <arg><replaceable>class</replaceable></arg>
+ <arg><replaceable>arguments</replaceable></arg>
+ </cmdsynopsis>
+
+<!-- <note> -->
+ <para>
+ You must additionally include <filename>tools.jar</filename> from
+ your Java developer's kit in your classpath.
+ </para>
+<!-- </note> -->
+
+ </refsect2>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajdee.gif b/docs/devGuideDB/ajdee.gif
new file mode 100644
index 000000000..e50832d0a
--- /dev/null
+++ b/docs/devGuideDB/ajdee.gif
Binary files differ
diff --git a/docs/devGuideDB/ajdee.xml b/docs/devGuideDB/ajdee.xml
new file mode 100644
index 000000000..7c42a90fd
--- /dev/null
+++ b/docs/devGuideDB/ajdee.xml
@@ -0,0 +1,452 @@
+<refentry id="ajdee">
+ <refnamediv>
+ <refname>AJDEE</refname>
+ <refpurpose>JDEE support for XEmacs and GNU Emacs </refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>AJDE for Emacs User's Guide</title>
+ <para>
+ This guide describes AspectJ-mode extensions of JDEE for GNU Emacs and
+ XEmacs, which
+ provides enhanced editing and management of AspectJ code via a minor
+ mode extension of JDE mode. AJDEE's AspectJ support builds on
+ <link linkend="aspectj-mode">aspectj-mode's</link> extension of
+ java-mode, also provided with the release.
+ Included in this document are guidance for AJDEE's <link
+ linkend="ajdee-featuresandusage">use</link>, including an <link
+ linkend="exploringspacewar">exploration of spacewar</link>, and <link
+ linkend="ajdee-installationetc">installation and compatibility</link>. See
+ the README file in AJDEE's distribution directory for
+ release-specific details.
+ </para>
+
+ <para>
+ In addition to the java-mode extensions provided by
+ <link linkend="aspectj-mode">aspectj-mode</link>, AJDEE provides
+ (see graphic):
+ <itemizedlist>
+ <listitem>
+ <para>
+ Viewing and navigation of aspect structures via the
+ the speedbar and Classes menu.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Basic support for completion.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Integrated Javadoc support.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ <inlinemediaobject id="ajdeemacsscreenshot">
+ <imageobject>
+ <imagedata fileref="ajdee.gif"/>
+ </imageobject>
+ </inlinemediaobject>
+ </para>
+ </refsect1>
+
+ <refsect1 id="ajdee-featuresandusage"><!-- Features and Usage -->
+ <title>AJDEE Features and Usage</title>
+ <para>
+ The AJDEE extensions of JDE require no special effort to use.
+ The speedbar and Classes menus provide additional sublists showing
+ crosscutting structure. Selecting items in those lists navigates to
+ the referenced item.
+ </para>
+
+ <refsect2>
+ <title>Aspect Structure and Navigation</title>
+
+ <refsect3>
+ <title>Enhancements to Speedbar in JDE Mode</title>
+ <para>
+ As a minor mode of JDE mode, AJDEE enhances the speedbar to
+ show the location of aspect, advice, and inter-type declarations.
+ The affects/affected-by relationships are shown in the speedbar
+ rather than embedding tags in the text (available as an option),
+ and selecting the items in the speedbar will perform the expected
+ navigation. The speedbar symbols have been extended for AspectJ as
+ follows (see right side of <link
+ linkend="ajdeemacsscreenshot">figure)</link>:
+ </para>
+
+ <table id="speedbarenhancements">
+ <title>Enhancements to Speedbar in JDE Mode</title>
+ <tgroup cols="2" colsep="1" rowsep="1" align="left">
+ <thead>
+ <row>
+ <entry>Indication</entry>
+ <entry>Meaning</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>
+ <literal>(+) </literal>
+ <emphasis><literal>name</literal></emphasis>
+ </entry>
+ <entry>
+ A class, interface, or aspect; double mouse-1 will
+ display its declarations
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>+ </literal>
+ <emphasis><literal>methodSignature</literal></emphasis>
+ </entry>
+ <entry>
+ Method has an advice that applies to it; double mouse-1
+ will display the relevant advice.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>+ </literal>
+ <emphasis><literal>adviceSignature</literal></emphasis>
+ </entry>
+ <entry>
+ Advice declared by the containing aspect; double mouse-1
+ will display affected methods.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>+ </literal>
+ <emphasis><literal>introductionSig</literal></emphasis>
+ </entry>
+ <entry>
+ Inter-type declaration declared by the containing class; double
+ mouse-1 will display affected methods or classes.
+ </entry>
+ </row>
+
+ <row>
+ <entry><literal>| | </literal>
+ <emphasis><literal>methodOrFieldSig</literal></emphasis>
+ </entry>
+ <entry>
+ Method or field has been declared by an aspect;
+ double mouse-1 on text will navigate to the declaration; a +
+ within the bars means that it has an advice that applies
+ to it.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ A minus (<literal>-</literal>) is displayed on the item when the
+ crosscutting items are displayed. AspectJ structure information is
+ derived from the last compile of your AspectJ program.
+ </para>
+ </refsect3>
+ </refsect2>
+
+ <refsect2>
+ <title>Compilation and JavaDoc</title>
+
+ <para>
+ The option <option>AspectJ Compile File Specification</option>
+ can be customized from the <guisubmenu>Customize options</guisubmenu>
+ under the <guimenu>AspectJ</guimenu> menu, changing the default
+ compile specification given to <command>ajc</command>.
+ See <link linkend="ajdee-installationetc">installation instructions</link>
+ for examples and other customizations.
+ </para>
+
+ <para>
+ AspectJ JavaDoc support is
+ enabled by setting <option>Jde Javadoc Command Path</option> to
+ invoke <command>ajdoc</command>. These are the default settings
+ provided in the installation instructions.
+ </para>
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1 id="exploringspacewar"><!-- Exploring the Spacewar Source Code -->
+ <title>Exploring the Spacewar Source Code</title>
+ <para>
+ To begin exploring Spacewar within emacs using JDE and AspectJ mode:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Compile spacewar.</para>
+ </listitem>
+
+ <listitem>
+ <para>Change into the <filename>spacewar</filename>
+ directory.</para>
+ </listitem>
+
+ <listitem>
+ <para>Type <userinput>emacs Ship.java</userinput>.</para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Pull down the <guimenu>JDE</guimenu> menu and select the
+ <guimenuitem>Speedbar</guimenuitem> entry to show the AspectJ
+ files in the directory. Note that <filename>Ship.java</filename>
+ is shown in red to denote that it is currently shown in the main
+ buffer.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Double-click with the left mouse button on the
+ <literal>+</literal> in front of the
+ <filename>Ship.java</filename> entry. It should display an entry
+ for the class <classname>Ship</classname>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Double-clicking on Ship will navigate to its declaration in
+ the buffer. Note that declarations of advice are annotated to
+ note the types of objects that they advise, declarations of
+ methods that are advised are annotated with the aspects that
+ advise them, and so forth.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Double-clicking on the <literal>+</literal> in front of either
+ will show the declared fields, methods, inter-type declarations, and
+ advice. A <literal>+</literal> in front of any field or method
+ means that it is introduced or advised; double-clicking will list
+ entries for the introducers/advisers; double-clicking on them
+ will navigate to their declarations. A <literal>+</literal> in
+ front of any inter-type declarations or advice will will display its
+ targets.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </refsect1>
+
+ <refsect1 id="ajdee-installationetc"><!-- Installation and Compatibility -->
+ <title>Installation and Compatibility</title>
+
+ <para> AJDEE requires the installation of
+ <ulink url="http://sunsite.auc.dk/jde">JDE 2.2.9beta4</ulink> or
+ higher and small edits to your <filename>.emacs</filename> file to
+ configure AJDEE and enable autoloading AJDEE when a
+ <filename>.java</filename> file is loaded.
+ </para>
+
+ <refsect2>
+ <title>Installation for enhancement of JDE mode</title>
+
+<!-- <note> -->
+ <para>
+ The first and last steps, with enhancements, can be found in the
+ example Emacs initialization file
+ <filename>sample.emacs</filename> and the sample JDE project
+ file <filename>sample.prj</filename> in the distribution. The
+ latter also demonstrates a way to enable AspectJ mode on a
+ per-project basis.
+ </para>
+<!-- </note> -->
+
+ <orderedlist>
+ <listitem>
+ <para>
+ Make sure AJDEE, aspectj-mode, JDE, and supporting packages are on
+ your <literal>load-path</literal> and are ``required''. This is an
+ example for the 1.0 release:
+ <programlisting>
+ ;; I keep my emacs packages in C:/Emacs
+ (setq load-path
+ (append
+ '(
+ "C:/Emacs/aspectj-emacsMode-1.0" ; for AJDEE
+ "C:/Emacs/aspectj-emacsAJDEE-1.0"
+ "C:/Emacs/jde-2.2.9beta6/lisp"
+ "C:/Emacs/elib-1.0" ; for JDEE
+ "C:/Emacs/speedbar-0.14beta2" ; for JDEE
+ "C:/Emacs/semantic-1.4beta12" ; for JDEE/speedbar
+ "C:/Emacs/eieio-0.17beta3" ; for JDEE
+ )
+ load-path))
+
+ (require 'jde)
+ (require 'ajdee) ; can also appear in prj.el</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>[Optional]</emphasis> add <literal>-emacssym</literal>
+ switch to the <filename>ajc</filename> and <filename>ajc.bat</filename>
+ files in your AspectJ tools installations (in the
+ <filename>/bin</filename> directory). If you invoke the compiler
+ outside Emacs, this will
+ ensure that your compiles always generate information for annotations
+ and the jump menu in the form of <literal>.ajesym</literal> files.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Customize AJDEE's compile options by
+ putting a version of the following in your
+ <filename>.emacs</filename> file or in a JDE project file
+ <filename>prj.el</filename> in your project's hierarchy (see the
+ <option>JDE Project File Name</option> option for the latter).
+ Here is a simple example:
+
+ <programlisting>
+ ;; A default version for simple projects, maybe good for
+ ;;; .emacs file.
+ (custom-set-variables
+ '(jde-compiler '("ajc" "ajc"))
+ '(jde-javadoc-command-path "ajdoc")
+
+ ;; ajc requires all files to be named for a compile
+ '(aspectj-compile-file-specification "*.java"))</programlisting>
+
+ Here is an example for spacewar, in
+ <filename>examples/spacewar</filename>.
+ <programlisting>
+ ;;; These options are for the spacewar, in examples/spacewar.
+ (custom-set-variables
+ '(jde-compiler '("ajc" "ajc"))
+ '(jde-javadoc-command-path "ajdoc")
+
+ ;; ajc provides an ``argfile'' mechanism for specifying all files.
+ '(aspectj-compile-file-specification "-argfile demo.lst")
+
+ ;; *if* compiling packages, name root dir for package hierarchy
+ ;; to tell ajc where .class files should go.
+ '(jde-compile-option-directory "..")
+ '(jde-run-working-directory ".."))
+ '(jde-run-application-class "spacewar.Game")</programlisting>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis>[XEmacs only]</emphasis> If you're installing JDE
+ yourself, be sure to closely follow the JDE installation
+ directions for XEmacs, otherwise you may get out of date JDE
+ <filename>.jar</filename> files.
+ </para>
+ </listitem>
+ </orderedlist>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Customizing Options</title>
+ <para>
+ Selecting <guimenuitem>Customize options</guimenuitem> from the
+ <guimenu>AspectJ</guimenu> menu displays a number of options that
+ customize AspectJ mode. These control whether annotations are shown
+ by default, and whether the bovinator set up by JDE runs.
+ <option>AspectJ Compile File Specification</option>, specifies a
+ compilation argument as
+ an alternative to the current buffer's file or the run class's file.
+ Example customizations are shown above and in the sample files
+ discussed above.
+ </para>
+ </refsect2>
+
+ </refsect1>
+
+
+ <refsect1>
+ <title>Usage and Upgrade Problems</title>
+
+ Please see the documentation for
+ <link linkend="aspectj-mode">aspectj-mode</link> for problems not
+ specific to AJDEE's features.
+
+ <itemizedlist>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Get
+ standard speedbar menus in JDE; no annotations display. Message:
+
+<screen>
+AspectJ Mode Warning: Can't find declarations file for...
+</screen>
+
+</para>
+
+ <para>AspectJ file has not been compiled with ajc and the <literal>-emacssym</literal>
+ flag,
+ or was compiled with an obsolete version of ajc. After compilation,
+ there should be a &lt;file&gt;.ajesym for every &lt;file&gt;.java in the
+ build. If .ajsym files are present but error persists, recompile. Note
+ that aspectj-mode for JDE has a fallback view for uncompiled files.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Navigations via the speedbar and
+ the jump menu are off, annotations are misplaced in the code. </para>
+
+ <para>AspectJ mode operates by querying data
+ derived from the most recent compile that includes the
+ <literal>-emacssym</literal> flag. Recompile the entire program with
+ ajc including the switch. Consider permanently installing the switch
+ by editing the ajc and ajc.bat files in the /bin file in your
+ distribution.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Java files that are part of a Java project not written
+ in AspectJ come up in aspectj-mode. </para>
+
+ <para>Emacs uses the file suffix (.java) to
+ determine which mode to invoke. You can either globally toggle the
+ AspectJ features from the AspectJ menu, or you can prevent AJDEE
+ from coming up by moving the (require 'ajdee) expression from
+ your .emacs file to a prj.el file in each AspectJ project's directory
+ (see sample.prj in the distribution).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Reported bug fixes and new features
+ to AJDEE are not seen, or ajdee.el cannot be found or loaded, with
+ message:
+
+<screen>
+Error in init file: File error: "Cannot open load file", "ajdee"
+</screen>
+
+</para>
+ <para>Your load-path variable (set in your .emacs)
+ is referring to an old release. Change your load-path to
+ point at the directory for the current release. See the sample.emacs
+ files in the distribution, for example.</para>
+ </listitem>
+ </itemizedlist>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- compile-command: "ant -quiet dev-html" -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajdeforte.xml b/docs/devGuideDB/ajdeforte.xml
new file mode 100644
index 000000000..910f62d81
--- /dev/null
+++ b/docs/devGuideDB/ajdeforte.xml
@@ -0,0 +1,215 @@
+<refentry>
+ <refnamediv>
+ <refname>
+ AspectJ Development Environment (AJDE) support for Forte
+ </refname>
+ <refpurpose>
+ Module extension to Sun's <ulink url="http://www.sun.com/forte/ffj">Forte
+ for Java</ulink> and
+ <ulink url="http://netbeans.org">NetBeans</ulink> IDEs.
+ </refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>Overview</title>
+ <para>
+ For release-specific documentation refer to the <ulink
+ url="http://aspectj.org/doc/dist/changes.html"> changes file</ulink>.
+ </para>
+
+ <para>
+ AJDE for Forte will allow you to:
+ <itemizedlist>
+
+ <listitem><para>compile AspectJ and Java files within the
+ IDE</para></listitem>
+
+ <listitem><para>browse the structure of your AspectJ
+ program</para></listitem>
+
+ <listitem><para>set up a compile configuration that determine which
+ files will be passed to the compiler</para></listitem>
+
+ </itemizedlist>
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Installation</title>
+ <para>
+
+ <itemizedlist>
+ <listitem><para>use the installer to place the "ajdeForForte.jar" and
+ "aspectjrt.jar" into the modules directory. This will also install
+ the two html files "LICENCE-AJDEFORTE.html" and
+ "README-AJDEFORTE.html".</para></listitem>
+
+ <listitem><para>start up, and in the "Tools" menu select "Global
+ Options" </para></listitem>
+
+ <listitem><para>right-click the "Modules" item and select "New Module
+ from File..." </para></listitem>
+
+ <listitem><para>find the ajdeForForte.jar in the directory that you
+ installed into (e.g. c:/forte4j/modules) and select it
+ </para></listitem>
+ </itemizedlist>
+
+ </para>
+ <para>
+ To uninstall follow Forte's documentation on un-installing modules, or
+ simply remove the file modules/aspectjForForte.jar from Forte's
+ install directory.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>Running AJDE for Forte</title>
+ <para>
+ <emphasis role="strong">3.1 Setting up the AspectJ Examples (in
+ NetBeans 3.3.1)</emphasis>
+
+ <imageobject>
+ <imagedata fileref="netbeans-building.gif"/>
+ </imageobject>
+
+ <itemizedlist>
+
+ <listitem><para>in the "Project" menu select "Project Manager"
+ </para></listitem>
+
+ <listitem><para>Click "New..." and enter "AspectJ Examples" as the
+ projects' name and click "OK". </para></listitem>
+
+ <listitem><para>In the "Filesystems" Explorer tab right click
+ "Filesystems", then select "Mount -&gt; Local Directory".
+ </para></listitem>
+
+ <listitem><para>browse into the AspectJ install directory (e.g.
+ "C:/apps/aspectj1.0") </para></listitem>
+
+ <listitem><para>select "examples" and click "Finish"
+ </para></listitem>
+
+
+ <listitem><para>In the "Tools" menu select "AspectJ -&gt; Start AJDE"
+ or just click on the "AJDE"
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="startAjde.gif"/>
+ </imageobject>
+ </inlinemediaobject>)
+ button (shown as label 1 of the screenshot).
+ </para></listitem>
+
+ </itemizedlist>
+ </para>
+ <para>
+ <emphasis role="strong">3.2 Compiling the Spacewar Example</emphasis>
+
+ <itemizedlist>
+
+ <listitem><para>After AJDE is started, a new "AspectJ" tab is added
+ to the explorer window. Click it. The next thing to do is to choose
+ a particular build, since there are many in the examples
+ distribution. To the right of the "Build" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="build.gif"/>
+ </imageobject>
+ </inlinemediaobject>)
+ there is a downward arrow. Click it, and select "spacewar/demo.lst"
+ (as in label 2 of the screenshot). This will start a build of the
+ demo configuration of spacewar. Clicking the "Build" button will
+ rebuild. </para></listitem>
+
+ <listitem><para>When the compile is finished and the "AspectJ
+ Explorer" structure is present navigate the structure by clicking
+ nodes (as shown in label 3 of the screenshot). Note that
+ associations between nodes appear with UML-style arrow icons and
+ italicized names and reperesent how a particular node in the
+ structure relates to others. In order to navigate these associations
+ expand the notes and click the corresponding links (in blue). These
+ links represent structure nodes elsewhere in the tree.
+ </para></listitem>
+
+ <listitem><para>If there are compilation errors, clickable messages
+ will appear (as in label 4 of the screenshot).
+ </para></listitem>
+
+ </itemizedlist>
+
+ </para>
+ <para>
+
+ <emphasis role="strong">3.3 Running the Spacewar Example</emphasis>
+ <itemizedlist>
+ <listitem><para>
+ In the "Filesystems" Explorer tab open the "spacewar"
+ directory, right click "spacewar/Game.java", and the select
+ "Execute".
+ </para></listitem>
+
+ <listitem><para>When finished executing switch back to the "Editing"
+ mode.</para></listitem>
+
+ <listitem><para>Select and build the "debug.lst" configuration as
+ described in 3.2 and execute again--you will notice that the debug
+ configuration adds a debug window used for tracing by including the
+ "Debug.java" aspect in the compile.</para></listitem>
+ </itemizedlist>
+
+ </para>
+
+ <emphasis role="strong">3.4 Debugging the Spacewar Example</emphasis>
+
+ <itemizedlist>
+ <listitem><para>
+ You must first add the filesystem to the project so
+ that the debugger can see the main class. Do this in
+ the "Project AspectJ Examples" tab in the explorer by
+ right clicking the root node and selecting "Add
+ Existing...".
+ </para></listitem>
+
+ <listitem><para>You may now need to add the AspectJ Runtime to the
+ project so that the debugger can see it. In the same way as described
+ in 3.1 select "Mount -&gt; Archive (JAR, Zip)". </para></listitem>
+
+ <listitem><para>Browse to the your lib/ext/aspectjrt.jar file within
+ your NetBeans install directory and click "Finish".</para></listitem>
+
+ <listitem><para>
+ Select "Project -&gt; Set Project Main Class..." in the
+ menu bar, browse to "spacewar/Game.java" in the
+ examples directory that you created and click "OK".
+ </para></listitem>
+
+ <listitem><para>
+ In the "Filesystems" Explorer tab open the "spacewar"
+ directory, click "Game.java", and the select "Debug
+ -&gt; Strat" from the menu bar.
+ </para></listitem>
+ </itemizedlist>
+
+ <para>
+ AspectJ-related options can be modified in the AJDE settings window.
+ </para>
+ <imageobject>
+ <imagedata fileref="netbeans-buildOptions.gif"/>
+ </imageobject>
+
+
+
+
+
+
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- compile-command: "ant -quiet dev-html" -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajdejbuilder.xml b/docs/devGuideDB/ajdejbuilder.xml
new file mode 100644
index 000000000..a201dd48d
--- /dev/null
+++ b/docs/devGuideDB/ajdejbuilder.xml
@@ -0,0 +1,266 @@
+r<refentry>
+ <refnamediv>
+ <refname>
+ AspectJ Development Environment (AJDE) support for JBuilder
+ </refname>
+ <refpurpose>
+ OpenTool extension Borland's <ulink url="http://www.borland.com/jbuilder">JBuilder IDE</ulink>.
+ </refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Overview</title>
+ <para>
+ For release-specific documentation refer to the <ulink url="http://aspectj.org/doc/dist/changes.html"> changes file</ulink>.
+ </para>
+ <para>
+ AJDE for JBuilder will allow you to:
+ <itemizedlist>
+ <listitem>
+ <para>compile AspectJ and Java files within the
+ IDE</para>
+ </listitem>
+ <listitem>
+ <para>browse the structure of your AspectJ
+ program</para>
+ </listitem>
+ <listitem>
+ <para>set up a compile configuration that determine which
+ files will be passed to the compiler</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Installation and Project Setup</title>
+ <para>
+ <command>Install procedure:</command> use the installer to place the
+ "ajdeForJBuilder.jar" and "aspectjrt.jar" into JBuilder's lib/ext
+ directory. This will also install the two html files
+ "LICENCE-AJDEJBUILDER.html" and "README-AJDEJBUILDER.html".
+ </para>
+ <para>
+ <command>Uninstall procedure:</command> remove "ajdeForJBuilder.jar"
+ and "aspectjrt.jar" (and the two html files, if you like) from the
+ "lib/ext" directory.
+ </para>
+ <para>
+ <command>Project setup:</command> follow the normal procedure for
+ JBuilder project setup (for an example of this please refer to the
+ example below). However, note that all of the source files to be
+ passed to the compiler must be added to your project either as files or
+ within a package that is added to the project. This is necessary
+ because -- unlike a pure Java compiler -- ajc does not search the
+ SOURCEPATH for classes.
+ </para>
+ <imageobject>
+ <imagedata fileref="jbuilder-building.gif" />
+ </imageobject>
+ <para>
+ <command>Starting and stopping AJDE:</command> select "Start AJDE" in
+ the "AspectJ" section of the "Tools" menu, or just click on the "AJDE"
+ (<inlinemediaobject id="ajdebutton">
+ <imageobject>
+ <imagedata fileref="startAjde.gif" />
+ </imageobject>
+ </inlinemediaobject>) button (label 1 in the first screenshot). This
+ will enable AJDE commands and will replace JBuilder's structure view
+ with the AspectJ Browser. To disable AJDE select "Stop AJDE" in the
+ same menu, or click the "AJDE" button again.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Compiling and Running the Project</title>
+ <para>
+ To compile the project select "Build project with ajc" from the AspectJ
+ toolbar, or click &lt;ctrl&gt;F11 while the editor pane is active. All
+ of the files contained in your project and within any packages and
+ subpackages that have been added to your project will be compiled. You
+ may also select a different configuration (as with label 2 in the first
+ screenshot). Then, structure of the currently visited file is shown
+ (see label 3 in the first scrrenshot). If there is a compile error,
+ the clickable error message is available (as with label 4 in the first
+ screenshot).
+ </para>
+ <para>
+ To run the project select "Run Project" from the AspectJ toolbar, or
+ click &lt;ctrl&gt;F12 while the editor pane is active. Note that the
+ "AspectJ Runtime" library must be added to your project in order to
+ run. If the library is not added you will see a "java.lang.NoClassDefFoundError: org/aspectj/lang/Signature" error. The library is created automatically for you from the runtime
+ in "jbuilderdir/lib/ext". You can also create a new library
+ to use the runtime from a different location. If you have not added the
+ library to the "Required Libraries" of your project it will be added
+ automatically when you restart JBuilder.
+ </para>
+ <para>
+ JBuilder7 users please note: when you set up a run/debug configuration
+ you must select the "Build Target" (at the bottom of the
+ "Runtime Properties" dialog) to be "&lt;None&gt;". This will ensure
+ that the Java compiler is not invoked on your AspectJ sources
+ before running or debugging the project.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Navigating the Program Structure</title>
+ <imageobject>
+ <imagedata fileref="jbuilder-structureNavigation.gif" />
+ </imageobject>
+ <para>
+ Navigation of program structure is provided by the <xref linkend="ajbrowser">AspectJ Browser</xref>, so apart from a JBuilder
+ look and feel, the extra navigation AspectJ allows work as described
+ there. In particular, you can use views with labels 1, 2 and 4 of the
+ second screenshot to navigate structure using the blue links, and you
+ can set filtering and navigate history using the toolbar shown by label
+ 3 of the second screenshot.
+ </para>
+ </refsect1>
+ <refsect1>
+ <title>Manipulating Build Configurations</title>
+ <para>
+ Build configurations can be manipulated adding, removing, and
+ editing build configuration files. The <xref linkend="ajbrowser">AspectJ Browser</xref> is used to select the
+ current build configuration. Configurations are represented by
+ ".lst" files which are described in the <xref linkend="ajc">ajc</xref> documentation.
+ </para>
+ <imageobject>
+ <imagedata fileref="jbuilder-configs.gif" />
+ </imageobject>
+ <refsect2>
+ <title>Adding and Removing Build Configurations</title>
+ <para>
+ By default all of the files contained in your project and
+ within any packages and subpackages that have been added to
+ your project will be compiled. In order to compile a different
+ configuration first add it to the project (by selecting
+ "Add Files / Packages..." in the "Project"
+ menu, and selecting the desired build configuration file (see
+ label 1 in the third screenshot).
+ </para>
+ </refsect2>
+ <refsect2>
+ <title>Editing Build Configurations</title>
+ <para>
+ Double click a build configuration file in JBuilder's
+ "Project Pane" in order to edit it. Configurations
+ can be edited as either text or in the graphical designer (see
+ labels 2 and 3 in the third screenshot)
+ </para>
+ </refsect2>
+ </refsect1>
+ <refsect1>
+ <title>Example: Setting up the "Spacewar" Sample Project</title>
+ <para>
+ To set up the Spacewar example first download it the <ulink url="http://aspectj.org/dl">examples distribution</ulink>. Then
+
+ <orderedlist>
+ <listitem>
+ <para>launch JBuilder</para>
+ </listitem>
+ <listitem>
+ <para>in the "File" menu select "New
+ project"</para>
+ </listitem>
+ <listitem>
+ <para>Select the location of the "aspectj/examples"
+ directory for the project. This is because the Spacewar
+ example uses both the "spacewar" and "coordination"
+ packages, so we set up the project where it can get at both
+ packages.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Choose a "jpr" project, either by typing in "Spacewar.jpr"
+ as the project name, or by typing "Spacewar" as the project
+ name and "jpr" as the type. Make sure "aspectj/examples"
+ is still the directory for the project. </para>
+ </listitem>
+ <listitem>
+ <para>click "Finish"</para>
+ </listitem>
+ <listitem>
+ <para>in the "Project" menu select "Project
+ properties..."</para>
+ </listitem>
+ <listitem>
+ <para>set the "Output path" entry to be the directory
+ where you want your classes to go</para>
+ </listitem>
+ <listitem>
+ <para>set the "Output path" entry to be the directory
+ where you want your classes to go</para>
+ </listitem>
+ <listitem>
+ <para>add "aspectjrt.jar" as a required library for
+ the project. This library is located in
+ "&lt;jbuilder-install-directory&gt;/lib/ext".
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ in the "Source" tab select the entry and click
+ "Edit" (by default JBuilder will set this directory to be
+ "examples/src" which does not exist)</para>
+ </listitem>
+ <listitem>
+ <para>
+ Select the "examples" directory for the
+ Souce. </para>
+ </listitem>
+ <listitem>
+ <para>click "OK" to close the "Project
+ Properties"dialog</para>
+ </listitem>
+ <listitem>
+ <para>in the leftmost pane you will notice
+ "Spacewar.jpr", right click this and select "Add to
+ project" in the popup, then "Add class/package..." in
+ thenext popup. Or directly choose "Add
+ files/packages". </para>
+ </listitem>
+ <listitem>
+ <para>&lt;cntrl&gt; select the "spacewar" and
+ "coordination" packages and then click "OK"; this will add
+ the two packages to your project</para>
+ </listitem>
+ <listitem>
+ <para>click the "Build Project" button
+ (<inlinemediaobject>
+ <imageobject>
+ <imagedata fileref="jbuilder-build.gif" />
+ </imageobject>
+ </inlinemediaobject>)
+ to compile the project</para>
+ </listitem>
+ <listitem>
+ <para>open the Structure View to browse the structure
+ of the program</para>
+ </listitem>
+ <listitem>
+ <para>click the "Run Project" button to play
+ Spacewar (make sure that you have set up the runtime
+ library as described above)</para>
+ </listitem>
+ <listitem>
+ <para>if you have not selected a class to run, you
+ will be prompted to do so: select the class
+ "spacewar.Game". </para>
+ </listitem>
+ <listitem>
+ <para>AspectJ related build options can be
+ manipulated in the "AJDE settings" window
+ </para>
+ <imageobject>
+ <imagedata fileref="jbuilder-buildOptions.gif" />
+ </imageobject>
+ </listitem>
+ </orderedlist>
+ </para>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- compile-command: "ant -quiet dev-html" -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/ajdoc.xml b/docs/devGuideDB/ajdoc.xml
new file mode 100644
index 000000000..be13c897c
--- /dev/null
+++ b/docs/devGuideDB/ajdoc.xml
@@ -0,0 +1,155 @@
+<refentry>
+ <refnamediv>
+ <refname>ajdoc</refname>
+ <refpurpose>generate HTML API documentation, including crosscutting structure (early-access)
+ </refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ajdoc</command>
+ <arg choice="opt">
+ -bootclasspath <replaceable>classpathlist</replaceable>
+ </arg>
+ <arg choice="opt">
+ -classpath <replaceable>classpathlist</replaceable>
+ </arg>
+ <arg choice="opt">-d <replaceable>path</replaceable></arg>
+ <arg choice="opt">-help</arg>
+ <arg choice="opt">-package</arg>
+ <arg choice="opt">-protected</arg>
+ <arg choice="opt">-private</arg>
+ <arg choice="opt">-public</arg>
+ <arg choice="opt">-overview <replaceable>overviewFile</replaceable></arg>
+ <arg choice="opt">
+ -sourcepath <replaceable>sourcepathlist</replaceable>
+ </arg>
+ <arg>-verbose</arg>
+ <arg>-version</arg>
+ <group>
+ <arg><replaceable>sourcefiles...</replaceable></arg>
+ <arg><replaceable>packages...</replaceable></arg>
+ <arg>@<replaceable>file...</replaceable></arg>
+ <arg>-argfile <replaceable>file...</replaceable></arg>
+ </group>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para>
+ Similar to <command>javadoc</command>,
+ <command>ajdoc</command> renders HTML documentation for pointcuts,
+ advice, and inter-type declarations, as
+ well as the Java constructs that Javadoc renders.
+ <command>ajdoc</command> also links
+ advice from members affected by the advice and
+ the inter-type declaration for members declared from aspects.
+ The aspect will be fully documented,
+ as will your target classes, including links to any
+ advice or declarations that affect the class.
+ That means, for example, that
+ you can see everything affecting a method when reading
+ the documentation for the method.
+ </para>
+
+ <para>
+ To run <command>ajdoc</command>, use one of the scripts in the
+ AspectJ <filename>bin</filename> directory.
+ The <command>ajdoc</command> implementation builds on Sun's <command>javadoc</command>
+ command line tool, and you use it in the same way with many of
+ the same options
+ (<command>javadoc</command> options are not documented here;
+ for more information on <command>javadoc</command> usage, see the
+ <ulink url="http://java.sun.com/j2se/javadoc/">Javadoc homepage</ulink>.)
+ </para>
+
+ <para>
+ As with <command>ajc</command> (but unlike <command>javadoc</command>),
+ you pass <command>ajdoc</command> all your aspect source files
+ and any files containing types affected by the aspects;
+ it's often easiest to just pass all the <filename>.java</filename> files
+ in your system.
+ Unlike <command>ajc</command>,
+ <command>ajdoc</command> will try to find package sources using the
+ specified sourcepath if you list packages on the command line.
+ </para>
+
+
+ <para>
+ To provide an argfile listing the source files, you can use
+ use the same argfile (<filename>@filename</filename>) conventions
+ as with <command>ajc</command>.
+ For example, the following documents all the source files listed
+ in <filename>argfile.lst</filename>, sending the output to
+ the <literal>docDir</literal> output directory.
+
+ <programlisting>ajdoc -d docDir @argfile.lst</programlisting>
+
+ See the <link linkend="ajc">ajc documentation</link>
+ for details on the text file format.
+ </para>
+
+ <para>
+ <command>ajdoc</command> currently requires the
+ <filename>tools.jar</filename> from J2SE 1.3 to be on the classpath.
+ Normally the scripts set this up, assuming that your <literal>JAVA_HOME</literal>
+ variable points to an appropriate installation of Java.
+ You may need to provide this jar when using a different
+ version of Java or a JRE.
+ </para>
+
+ </refsect1>
+ <refsect1>
+ <title>Examples</title>
+ <example id="ajdocdocumentingspacewar"> <!-- docbook bug - rendering this as example 4? -->
+ <title>Documenting Spacewar</title>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Change into the <filename>examples</filename> directory.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Type <userinput>mkdir doc</userinput> to create the
+ destination directory for the documentation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Type <userinput>ajdoc -private -d doc spacewar
+ coordination</userinput> to generate the documentation.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ (Use <literal>-private</literal> to get all members, since
+ may of the interesting ones in spacewar are not public.)
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>
+ Type <userinput>ajdoc -private -d doc @spacewar/demo.lst</userinput>
+ to use the argfile associated with Spacewar.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ To view the documentation, open the file <filename>index.html</filename>
+ in the <filename>doc</filename> directory using a web browser.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </example>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/antsupport.xml b/docs/devGuideDB/antsupport.xml
new file mode 100644
index 000000000..1b97968aa
--- /dev/null
+++ b/docs/devGuideDB/antsupport.xml
@@ -0,0 +1,23 @@
+<refentry>
+ <refnamediv>
+ <refname>Ant Support</refname>
+ <refpurpose>Support of Ant</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>ant </command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1>
+ <title>Description</title>
+ <para></para>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/aspectj-mode.gif b/docs/devGuideDB/aspectj-mode.gif
new file mode 100644
index 000000000..9b07fdb33
--- /dev/null
+++ b/docs/devGuideDB/aspectj-mode.gif
Binary files differ
diff --git a/docs/devGuideDB/aspectj-mode.xml b/docs/devGuideDB/aspectj-mode.xml
new file mode 100644
index 000000000..b54837964
--- /dev/null
+++ b/docs/devGuideDB/aspectj-mode.xml
@@ -0,0 +1,354 @@
+<refentry id="aspectj-mode">
+ <refnamediv>
+ <refname>AspectJ-mode</refname>
+ <refpurpose>support for XEmacs and GNU Emacs
+ </refpurpose>
+ </refnamediv>
+
+ <refsect1>
+ <title>AspectJ-mode User's Guide</title>
+ <para>
+ This guide describes aspectj-mode for GNU Emacs and XEmacs, which
+ provides enhanced editing and management of AspectJ code via a minor
+ mode extension of java-mode. Included in this document
+ are guidance for aspectj-mode's <link
+ linkend="ajmode-featuresandusage">use</link>, and
+ <link linkend="ajmode-installationetc">installation and compatibility</link>.
+ See the README file in the aspectj-mode's distribution directory for
+ release-specific details.
+ </para>
+
+ <para>
+ AspectJ minor mode provides (see graphic):
+ <itemizedlist>
+ <listitem>
+ <para>
+ Viewing and navigation of aspect structures, permitting
+ navigation between aspect code and the code that it affects, via
+ a `jump' menu (and in the speedbar and Classes menu for JDE
+ users).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Source code annotation of inter-type and advice declarations,
+ as well as the code they affect.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ AspectJ-style compilation, using .lst files to generate a
+ compilation submenu.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Highlighting of AspectJ keywords and declaration names.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+ </para>
+
+ <para>
+ The first two are derived from ajc's last build of the AspectJ program.
+ An example usage is given below.
+ </para>
+
+ <para>
+ <inlinemediaobject id="aspectjmodescreenshot">
+ <imageobject>
+ <imagedata fileref="aspectj-mode.gif"/>
+ </imageobject>
+ </inlinemediaobject>
+ </para>
+ </refsect1>
+
+ <refsect1 id="ajmode-featuresandusage"><!-- Features and Usage -->
+ <title>Features and Usage</title>
+ <para>
+ All commands governing AspectJ mode are available from the AspectJ menu
+ on the toolbar. Besides those described below, there is a menu item
+ <guimenuitem>Customize options</guimenuitem> for viewing and customizing
+ the options of the mode and <guimenuitem>AJ Mode user guide</guimenuitem>
+ to view this file. Keyword and declaration highlighting is enabled above
+ the minimal level of highlighting.
+ </para>
+
+ <para>
+ By default, AspectJ mode is automatically turned on when a buffer
+ named with a <filename>.java</filename> suffix is entered.
+ The command
+ <command>M-x aspectj-mode-in-force-toggle</command> globally toggles
+ the features of the mode, easing quickly moving between
+ AspectJ and Java projects (also available as <guimenuitem>AspectJ mode
+ extensions</guimenuitem> in the AspectJ menu).
+ </para>
+
+ <refsect2>
+ <title>Aspect Structure and Navigation</title>
+
+ <para>
+ AspectJ minor mode highlights aspect relationships in the text with
+ textual annotations on the program source (optionally can be turned
+ off), such as the <literal>[Player, Robot, Ship]</literal> marking after the advice in EnsureShipIsAlive
+ at the bottom of the <link linkend="aspectjmodescreenshot">figure</link>,
+ which indicates that the advice refers to join points within Ship
+ objects. The following commands (also available from the menu) manage
+ annotations and navigation:
+ </para>
+
+ <table id="minormodecommands">
+ <title>
+ AspectJ Minor Mode Commands for Annotations and Navigation
+ </title>
+ <tgroup cols="2" colsep="1" rowsep="1" align="left">
+ <thead>
+ <row>
+ <entry>Command (keyboard shortcut)</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+
+ <tbody>
+ <row>
+ <entry>M-x aspectj-jump-menu (C-x C-j)</entry>
+ <entry>
+ Display popup menu of advisers, advisees, and inter-type declarations.
+ Navigate to item by selecting with mouse
+ (see <link linkend="aspectjmodescreenshot2">figure</link> below).
+ </entry>
+ </row>
+ <row>
+ <entry>M-x aspectj-show-annotations</entry>
+ <entry>
+ Add crosscut annotations on the text on current buffer.
+ </entry>
+ </row>
+
+ <row>
+ <entry>M-x aspectj-dont-show-annotations</entry>
+ <entry>
+ Remove crosscut annotations from text on current buffer.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>
+ The default for whether annotations are shown or not can be
+ customized by selecting <guimenuitem>Customize options</guimenuitem>
+ from the <guimenu>AspectJ</guimenu> menu.
+ </para>
+
+ <para>
+ <inlinemediaobject id="aspectjmodescreenshot2">
+ <imageobject>
+ <imagedata fileref="aspectj-mode2.gif"/>
+ </imageobject>
+ </inlinemediaobject>
+ </para>
+
+ </refsect2>
+
+ <refsect2>
+ <title>Compilation</title>
+
+ <para>
+ The <guisubmenu>Compile</guisubmenu> submenu
+ accessible from the <guimenu>AspectJ</guimenu> menu presents the
+ known<filename> .lst</filename> files for the project. Selecting
+ one compiles the project with that <filename>.lst</filename> file
+ and remembers that for future compiles. The
+ <guimenuitem>Compile...</guimenuitem> command accessible from the
+ Emacs <guimenu>Tools</guimenu> menu is customized through the
+ project customization option <option>Aspectj Tools Compile
+ Command</option>, customizable from the
+ <guimenu>AspectJ</guimenu> menu.
+ </para>
+
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1 id="ajmode-installationetc"><!-- Installation and Compatibility -->
+ <title>Installation and Compatibility</title>
+
+ <para> AspectJ mode requires the installation of <ulink
+ url="http://www.gnu.org/software/emacs/">GNU Emacs 20.3.1</ulink>
+ or <ulink url="http://www.xemacs.org/">XEmacs 21.1.14 (Unix/Linux)</ulink>,
+ or <ulink url="http://www.xemacs.org/">XEmacs 21.4 (Windows)</ulink>,
+ or higher. In general, the most recent non-alpha/beta versions of these
+ are recommended. A web browser is required to view this documentation
+ via Emacs. Small modifications to the <filename>.emacs</filename> file
+ configures AspectJ mode and enables autoloading AspectJ mode when a
+ <filename>.java</filename> file is loaded.
+ </para>
+
+ <refsect2>
+ <title>
+ Installation
+ </title>
+
+<!-- <note> -->
+ <para>
+ Step 1, with enhancements, can be found in the example Emacs
+ initialization file <filename>sample.emacs</filename> in the
+ distribution.
+ </para>
+<!-- </note> -->
+
+ <orderedlist>
+ <listitem>
+ <para>
+ The files in this package need to be in the load-path and
+ ``required''. For example, for the 1.0 release:
+ <programlisting>
+ ;; I keep my emacs packages in C:/Emacs
+ (setq load-path (cons "C:/Emacs/aspectj-emacsMode-1.0" load-path))
+ (require 'aspectj-mode)</programlisting>
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <emphasis>[Optional]</emphasis> add <literal>-emacssym</literal>
+ switch to the <filename>ajc</filename> and <filename>ajc.bat</filename>
+ files in your AspectJ tools installations (in the
+ <filename>/bin</filename> directory). If you invoke the compiler
+ outside Emacs, this will
+ ensure that your compiles always generate information for annotations
+ and the jump menu in the form of <literal>.ajesym</literal> files.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <!-- TBD: Change to something less bogus. -->
+ <emphasis>[XEmacs only]</emphasis> Go to the
+ <filename>xemacs-packages/lisp</filename> directory of your
+ XEmacs distribution and move the <filename>jde</filename>
+ directory to someplace harmless. Otherwise, Java files will come
+ up in JDE mode.
+ </para>
+ </listitem>
+
+ </orderedlist>
+ </refsect2>
+
+ <refsect2>
+ <title>Customizing Options</title>
+ <para>
+ Selecting <guimenuitem>Customize options</guimenuitem> from the
+ <guimenu>AspectJ</guimenu> menu displays a number of options that
+ customize AspectJ mode. These control whether annotations are shown
+ by default, as well as a
+ number of options controlling compilation and beanshell for
+ java-mode.
+ Example customizations are given in the file
+ <filename>sample.emacs</filename> in the distribution.
+ </para>
+ </refsect2>
+
+ </refsect1>
+
+ <refsect1>
+ <title>Usage and Upgrade Problems</title>
+
+ <itemizedlist>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: No annotations show. Message:
+
+<screen>
+AspectJ Mode Warning: Can't find declarations file for...
+</screen>
+
+</para>
+
+ <para>AspectJ file has not been compiled with ajc and the <literal>-emacssym</literal>
+ flag,
+ or was compiled with an obsolete version of ajc. After compilation,
+ there should be a &lt;file&gt;.ajesym for every &lt;file&gt;.java in the
+ build. If .ajsym files are present but error persists, recompile. Note
+ that aspectj-mode for JDE has a fallback view for uncompiled files.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Annotations are misplaced in the
+ code. </para>
+
+ <para>AspectJ mode operates by querying data
+ derived from the most recent compile that includes the
+ <literal>-emacssym</literal> flag. Recompile the entire program with
+ ajc including the switch. Consider permanently installing the switch
+ by editing the ajc and ajc.bat files in the /bin file in your
+ distribution.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: New customization option settings were saved
+ for future sessions, but do not show up when Emacs is restarted.
+ </para>
+
+ <para>You may have two sets of saved settings in
+ your .emacs file, and Emacs updated the first one, which may be shadowed
+ by the second.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Java files that are part of a Java project not written
+ in AspectJ come up in aspectj-mode. </para>
+
+ <para>Emacs uses the file suffix (.java) to
+ determine which mode to invoke. You can either globally toggle the
+ AspectJ features from the AspectJ menu.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: Reported bug fixes and new features
+ to aspectj-mode are not seen, or aspectj-mode.el cannot be found or
+ loaded, with message:
+
+<screen>
+Error in init file: File error: "Cannot open load file", "aspectj-mode"
+</screen>
+
+</para>
+ <para>Your load-path variable (set in your .emacs)
+ is referring to an old release. Change your load-path to
+ point at the directory for the current release. See the sample.emacs
+ files in the distribution, for example.</para>
+ </listitem>
+
+ <listitem>
+ <para><emphasis>Symptom</emphasis>: When trying to get a jump menu,
+ I get the message "No crosscut elements at point" even though
+ there is a [list] on the same line.
+ </para>
+
+ <para>The caret (point) is probably on or after the list.
+ To see the crosscut elements you need to hit the jump menu
+ on the same line that the annotated elements appear as a list
+ of items surrounded by '[' and ']' on the same line as the
+ affected declaration. If the caret is on the same line as the
+ elements and before the list (i.e. not at the end of the
+ list of elements) the jump menu should work.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </refsect1>
+</refentry>
+
+<!-- Local variables: -->
+<!-- fill-column: 79 -->
+<!-- compile-command: "ant -quiet dev-html" -->
+<!-- sgml-local-ecat-files: devguide.ced -->
+<!-- sgml-parent-document:("devguide.sgml" "book" "refentry") -->
+<!-- End: -->
diff --git a/docs/devGuideDB/aspectj-mode2.gif b/docs/devGuideDB/aspectj-mode2.gif
new file mode 100644
index 000000000..f9e718385
--- /dev/null
+++ b/docs/devGuideDB/aspectj-mode2.gif
Binary files differ
diff --git a/docs/devGuideDB/devguide.xml b/docs/devGuideDB/devguide.xml
new file mode 100644
index 000000000..5b2b1ba30
--- /dev/null
+++ b/docs/devGuideDB/devguide.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
+ "../../lib/docbook/docbook-dtd/docbookx.dtd"
+[
+<!ENTITY ajc SYSTEM "ajc.xml">
+<!ENTITY ajdb SYSTEM "ajdb.xml">
+<!ENTITY ajdoc SYSTEM "ajdoc.xml">
+<!ENTITY antsupport SYSTEM "antsupport.xml">
+<!ENTITY ajbrowser SYSTEM "ajbrowser.xml">
+<!ENTITY ajdejbuilder SYSTEM "ajdejbuilder.xml">
+<!ENTITY ajdeforte SYSTEM "ajdeforte.xml">
+<!ENTITY aspectj-mode SYSTEM "aspectj-mode.xml">
+<!ENTITY ajdee SYSTEM "ajdee.xml">
+]>
+
+<book>
+ <bookinfo>
+ <title>The AspectJ<superscript>tm</superscript> Development Environment 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 user's guide describes the tools which are part of the
+ AspectJ development environment. A companion guide describes the
+ AspectJ language.
+ </para>
+ </abstract>
+ </bookinfo>
+
+ <reference>
+ <title>The Command Line Tools</title>
+ &ajc;
+ &ajdb;
+ &ajdoc;
+ </reference>
+
+ <reference>
+ <title>The GUI Tools</title>
+ &ajbrowser;
+ &ajdejbuilder;
+ &ajdeforte;
+ &aspectj-mode;
+ &ajdee;
+ </reference>
+
+</book>
+
+<!--
+Local Variables:
+compile-command:"ant -quiet dev-html"
+fill-column: 79
+sgml-indent-step: 3
+sgml-local-ecat-files:devguide.ced
+sgml-namecase-general: t
+End:
+-->
diff --git a/docs/devGuideDB/jbuilder-buildOptions.gif b/docs/devGuideDB/jbuilder-buildOptions.gif
new file mode 100644
index 000000000..5a34c9309
--- /dev/null
+++ b/docs/devGuideDB/jbuilder-buildOptions.gif
Binary files differ
diff --git a/docs/devGuideDB/jbuilder-building.gif b/docs/devGuideDB/jbuilder-building.gif
new file mode 100644
index 000000000..63fe151a2
--- /dev/null
+++ b/docs/devGuideDB/jbuilder-building.gif
Binary files differ
diff --git a/docs/devGuideDB/jbuilder-configs.gif b/docs/devGuideDB/jbuilder-configs.gif
new file mode 100644
index 000000000..1a262c1cf
--- /dev/null
+++ b/docs/devGuideDB/jbuilder-configs.gif
Binary files differ
diff --git a/docs/devGuideDB/jbuilder-structureNavigation.gif b/docs/devGuideDB/jbuilder-structureNavigation.gif
new file mode 100644
index 000000000..bdd7ce815
--- /dev/null
+++ b/docs/devGuideDB/jbuilder-structureNavigation.gif
Binary files differ
diff --git a/docs/devGuideDB/netbeans-buildOptions.gif b/docs/devGuideDB/netbeans-buildOptions.gif
new file mode 100644
index 000000000..5cd5e75d2
--- /dev/null
+++ b/docs/devGuideDB/netbeans-buildOptions.gif
Binary files differ
diff --git a/docs/devGuideDB/netbeans-building.gif b/docs/devGuideDB/netbeans-building.gif
new file mode 100644
index 000000000..7ef8f4500
--- /dev/null
+++ b/docs/devGuideDB/netbeans-building.gif
Binary files differ
diff --git a/docs/dist/doc/ant-ajc-task.html b/docs/dist/doc/ant-ajc-task.html
new file mode 100644
index 000000000..602c48938
--- /dev/null
+++ b/docs/dist/doc/ant-ajc-task.html
@@ -0,0 +1,389 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>AjcTask Ant Support for AspectJ 1.1</title>
+</head>
+<body>
+
+<h2>
+<a NAME="ajc"></a>AjcTask Ant Support for AspectJ 1.1</h2>
+
+<h3>
+Description</h3>
+
+This task uses the AspectJ<small><sup>tm</sup></small> 1.1 compiler
+<code>ajc</code>.
+
+The AspectJ compiler can be used like
+ <a href="http://jakarta.apache.org/ant/manual/CoreTasks/javac.html">Javac</a>
+to compile Java sources, but it can also compile AspectJ sources or
+weave binary aspects with Java bytecode. It can run in normal "batch" mode
+or in an "incremental" mode, where it only recompiles files it has to revisit.
+For more information on <tt>ajc</tt>, see the links from
+the <a href="index.html">AspectJ docs home</a>. The main things to remember:
+<ul>
+ <li>In incremental mode, sources may only be specified using source root directories.
+ </li>
+ <li>A .class file may only be woven once. That means
+ binaries in injars or aspectjpath must have been compiled with jikes or javac
+ or, if using ajc, with noweave.
+ </li>
+</ul>
+This task is named <tt>iajc</tt> now to avoid conflict with the
+1.0 task <tt>ajc</tt>, but the name may change to <tt>ajc</tt> in
+the future.
+<p>
+See <a href="#compilerMessages">below</a> for
+an introduction to handling compiler messages programmatically.
+
+<p>
+<h3>
+Parameters</h3>
+
+<h4>Parameters supported by <code>ajc</code></h4>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP><b>Attribute</b></td>
+
+<td VALIGN=TOP><b>Description</b></td>
+
+<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+</tr>
+
+<tr>
+<th colspan="3">Specifying source and destination files</th>
+</tr>
+
+<td VALIGN=TOP>sourceroots</td>
+
+<td VALIGN=TOP>a list of base directories of the source files.
+All source files (.java and .aj) in the base directories are compiled.
+ May also be specified as a <a href="nestedElements">nested element</a>.
+</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes, in incremental mode.</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>outjar</td>
+<td VALIGN=TOP>Path to an output jar to generate with all output classes.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>destdir</td>
+<td VALIGN=TOP>Specify where to place the generated class files.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>classpath</td>
+<td VALIGN=TOP>the classpath required by the source files to compile.
+ May also be specified as a <a href="nestedElements">nested element</a>.
+</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>srcdir</td>
+<td VALIGN=TOP>the nested source base directory to compile,
+ specified as a <a href="nestedElements">nested element</a>.
+</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>aspectpath</td>
+<td VALIGN=TOP>the aspectpath to use -- like classpath, only for
+read-only, binary aspect libraries (only accepts jar/zip files, no directories).
+May also be specified as a <a href="nestedElements">nested element</a>.
+</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>bootclasspath</td>
+<td VALIGN=TOP>location of bootstrap class files.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>classpathref</td>
+<td VALIGN=TOP>the classpath to use, given as a<a href="http://jakarta.apache.org/ant/manual/using.html#references">
+reference</a> to a PATH defined elsewhere.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>bootclasspathref</td>
+<td VALIGN=TOP>location of bootstrap class files, given as a <a href="http://jakarta.apache.org/ant/manual/using.html#references">reference</a>
+to a PATH defined elsewhere.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<th colspan="3">Specifying compiler behavior</th>
+</tr>
+
+<tr>
+<td VALIGN=TOP>noweave</td>
+<td VALIGN=TOP>If true, produce binaries for the -injars option (only) --
+defaults to <tt>false</tt>.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>incremental</td>
+ <td VALIGN=TOP>build once, then recompile on demand only required files;
+ defaults to <tt>false</tt>.
+ By default, files are recompiled based on input passed to stdin
+ (see tagfile)</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>tagfile</td>
+ <td VALIGN=TOP>File that controls when incremental builds are done
+ and when the task completes.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>X</td>
+ <td VALIGN=TOP>Set experimental option(s), using comma-separated list
+ of accepted options (unlisted here -- for XLint, use
+ the xlint entries). Options should not contain the leading X.</td> <!-- XXX list -->
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+
+<tr>
+<th colspan="3">Specifying compiler side-effects and messages</th>
+</tr>
+
+<tr>
+<td VALIGN=TOP>verbose</td>
+<td VALIGN=TOP>whether to emit compiler status messages during the compile;
+defaults to <tt>false</tt>.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>version</td>
+<td VALIGN=TOP>if true, do not compile - just print AspectJ version;
+defaults to <tt>false</tt>.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>help</td>
+<td VALIGN=TOP>if true, just print help for the command-line compiler;
+defaults to <tt>false</tt>.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>Xlintenabled</td>
+<td VALIGN=TOP>same as <tt>xlint:all</tt>,
+whether to emit language usage messages during the compile;
+defaults to <tt>false</tt>.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>Xlintfile</td>
+<td VALIGN=TOP>specify property file containing name:level associations
+for any overrides to the default associations for language usage
+messaged emitted during the compile.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<!--
+<tr>
+<td VALIGN=TOP>Xlint</td>
+<td VALIGN=TOP>Specify which language usage messages to emit
+during compile, using comma-separated list of entries.
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+-->
+
+<tr>
+ <td VALIGN=TOP>failonerror</td>
+ <td VALIGN=TOP>whether the build continues notwithstanding compile errors;
+ defaults to <tt>true</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+<td VALIGN=TOP>messageholderclass</td>
+<td VALIGN=TOP>Specify a class to use as the message holder for the compile
+process. The entry must be a fully-qualified name of a class resolveable
+from the task classpath complying with the <tt>org.aspectj.bridge.IMessageHolder</tt>
+interface and having a public no-argument constructor.</td>
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+
+<tr>
+<th colspan="3">Eclipse compiler options</th>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>nowarn</td>
+ <td VALIGN=TOP>same as <tt>warn:none</tt>;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>deprecation</td>
+ <td VALIGN=TOP>same as <tt>warn:deprecation</tt>;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>warn</td>
+ <td VALIGN=TOP>one or more comma-separated warning specifications:
+constructorName,
+packageDefaultMethod,
+deprecation,
+maskedCatchBlocks,
+unusedLocals,
+unusedArguments,
+unusedImports,
+syntheticAccess, or
+assertIdentifier.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>debug</td>
+ <td VALIGN=TOP>same as <tt>debug:lines,vars,source</tt></td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>debuglevel</td>
+ <td VALIGN=TOP>comma-separated list lines, vars, or source,
+ indicating to add debugging information for lines,
+ variables, or source</tt></td> <!-- XXX weak -->
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>PreserveAllLocals</td>
+ <td VALIGN=TOP>code gen preserve all local variables (for debug purposes);
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>noimporterror</td>
+ <td VALIGN=TOP>no errors for unresolved imports;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>referenceinfo</td>
+ <td VALIGN=TOP>compute reference info;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>log</td>
+ <td VALIGN=TOP>File to log compiler messages to.</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>encoding</td>
+ <td VALIGN=TOP>default source encoding format</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>proceedonerror</td>
+ <td VALIGN=TOP>keep compiling when error, dumping class files with problem methods;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>progress</td>
+ <td VALIGN=TOP>show progress (requires log);
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>time</td>
+ <td VALIGN=TOP>display speed information;
+ defaults to <tt>false</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>noexit</td>
+ <td VALIGN=TOP>disable System.exit (kills Ant -- use failonerror);
+ defaults to <tt>true</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>target</td>
+ <td VALIGN=TOP>Specify target class file format (must be "1.1" or "1.2");
+ defaults to 1.1 class file.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>compliance</td>
+ <td VALIGN=TOP>Set "1.3" or "1.4" source compliance level
+ (e.g., no import from default package in 1.4);
+ defaults to 1.3 compliance level.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>source</td>
+ <td VALIGN=TOP>source assertion mode ("1.3" or "1.4");
+ default depends on compliance mode.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+</table>
+
+<a name="nestedElements"></a>
+<h3>Nested Elements</h3>
+This taskdef should support nested elements as the old one did;
+see <a href="taskdef-ajc10.html#nestedElements">taskdef-ajc10.html#nestedElements</a>.
+
+<a name="compilerMessages"></>
+<h3>Programmatically handling compiler messages</h3>
+
+Users may specify a message holder which is passed all
+messages generated by the compiler synchronously. This overrides all of the normal
+message printing, but does not prevent the task from failing if failonerror is true
+and errors or exceptions were encountered.
+
+Handling messages programmatically could be useful
+when using the compiler to inspect code.
+If aspects consist of declare [error|warning], then
+the compiler can act to detect invariants in the code being processed.
+For code to compare expected and actual messages, see the AspectJ
+testing module (which is not included in the binary distribution).
+
+
+<hr>
+<center>
+</center>
+
+</body>
+</html>
diff --git a/docs/dist/doc/ant-ajc10-task.html b/docs/dist/doc/ant-ajc10-task.html
new file mode 100644
index 000000000..03d4b3e88
--- /dev/null
+++ b/docs/dist/doc/ant-ajc10-task.html
@@ -0,0 +1,383 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta http-equiv="Content-Language" content="en-us">
+ <title>Ajc10 Ant Task</title>
+</head>
+<body>
+
+<h2>
+<a NAME="ajc10"></a>Ajc10 Ant Task</h2>
+
+<h3>
+Description</h3>
+This task is provided for backwards compatibility with build scripts
+created for the AspectJ 1.0 <tt>ajc</tt> task. Developers using only
+AspectJ 1.1 should upgrade their scripts to use the newer task.
+This task is deprecated and may not be supported in the future.
+Options no longer supported in 1.1 are still accepted, but have
+no effect, other than to be listed in a warning emitted by the task.
+<p>
+This task compiles using the AspectJ<small><sup>tm</sup></small> compiler <code>ajc</code>;
+you can use it in place of the
+ <a href="http://jakarta.apache.org/ant/manual/CoreTasks/javac.html">Javac</a> task.
+
+The interface is like the <tt>Javac</tt> task interface, except it also accepts
+<a href="#ajc-parameters">parameters unique to <code>ajc</code></a>.
+Of these, most no longer have any effect (nocomments, preprocess, workingdir,
+maxmemory, jvmarg), but argfiles are still supported. (For more information
+on argfiles, see <a href="#argfiles">below</a>.)
+<p>
+
+<h3>
+Parameters</h3>
+
+<h4>Parameters supported by <code>ajc</code></h4>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP><b>Attribute</b></td>
+
+<td VALIGN=TOP><b>Description</b></td>
+
+<td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>srcdir</td>
+
+<td VALIGN=TOP>the base directory of the java files. (See <a href="#nestedElements">note</a>)</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes, unless you use <tt>argfile</tt>
+or nested <tt>&lt;src></tt> elements.
+</tr>
+
+<tr>
+<td VALIGN=TOP>destdir</td>
+
+<td VALIGN=TOP>Specify where to place the generated class files.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>includes</td>
+
+<td VALIGN=TOP>comma-separated list of patterns of files that must be included;
+<b>no</b>
+files are included when omitted.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>includesfile</td>
+
+<td VALIGN=TOP>the name of a file that contains include patterns.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>excludes</td>
+
+<td VALIGN=TOP>comma-separated list of patterns of files that must be excluded;
+no files (except default excludes) are excluded when omitted.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>excludesfile</td>
+
+<td VALIGN=TOP>the name of a file that contains exclude patterns.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>defaultexcludes</td>
+
+<td VALIGN=TOP>whether default excludes should be used (<tt>yes</tt>
+| <tt>no</tt>); default excludes are used when omitted.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>classpath</td>
+
+<td VALIGN=TOP>the classpath to use.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>bootclasspath</td>
+
+<td VALIGN=TOP>location of bootstrap class files.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>classpathref</td>
+
+<td VALIGN=TOP>the classpath to use, given as a<a href="http://jakarta.apache.org/ant/manual/using.html#references">
+reference</a> to a PATH defined elsewhere.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>bootclasspathref</td>
+
+<td VALIGN=TOP>location of bootstrap class files, given as a <a href="http://jakarta.apache.org/ant/manual/using.html#references">reference</a>
+to a PATH defined elsewhere.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>extdirs</td>
+
+<td VALIGN=TOP>location of installed extensions </td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>debug</td>
+
+<td VALIGN=TOP>whether debug information should be included in classes output;
+defaults to <tt>false</tt>.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>deprecation</td>
+
+<td VALIGN=TOP>whether compiler should emit messages about
+usage of deprecated API; defaults to <tt>false</tt>.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>verbose</td>
+
+<td VALIGN=TOP>whether to emit compiler status messages during the compiler;
+defaults to <tt>false</tt>.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>version</td>
+ <td VALIGN=TOP>print ajc version and exit</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>failonerror</td>
+
+ <td VALIGN=TOP>whether the build continues notwithstanding compile errors;
+ defaults to <tt>true</tt>.&nbsp;</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+
+<tr>
+ <td VALIGN=TOP>source</td>
+
+ <td VALIGN=TOP>Value of -source option - ignored unless "1.4"</td>
+
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+</table>
+
+<h4>
+<a NAME="ajc-parameters-ignored"></a>Parameters that used to be ignored by
+the <code>ajc</code> taskdef, but now are supported or cause failures</h4>
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr>
+<td VALIGN=TOP><b>Attribute</b></td>
+
+<td VALIGN=TOP><b>Description</b></td>
+
+<td ALIGN=CENTER VALIGN=TOP><b>Support</b></td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>encoding</td>
+
+<td VALIGN=TOP>encoding of source files.</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes?</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>optimize</td>
+
+<td VALIGN=TOP>whether source should be compiled with optimization</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes?</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>target</td>
+
+<td VALIGN=TOP>generate class files for specific VM version (e.g., <tt>1.1</tt>
+or <tt>1.2</tt>).</td>
+
+<td ALIGN=CENTER VALIGN=TOP>Yes</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>depend</td>
+
+<td VALIGN=TOP>enables dependency-tracking </td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>includeAntRuntime</td>
+
+<td VALIGN=TOP>whether to include the Ant run-time libraries</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+<td VALIGN=TOP>includeJavaRuntime</td>
+
+<td VALIGN=TOP>whether to include the run-time libraries from the
+executing VM</td>
+
+<td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+<tr>
+ <td VALIGN=TOP>threads</td>
+ <td VALIGN=TOP>Multi-threaded compilation</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+</table>
+
+
+<h4>
+<a NAME="ajc-parameters"></a>Parameters unique to <code>ajc</code></h4>
+<u>Note</u>: Many of the unique parameters in AspectJ 1.0 are no longer supported,
+and fork is not supported yet.
+
+<table BORDER CELLSPACING=0 CELLPADDING=2 >
+<tr> <td VALIGN=TOP><b>Attribute</b></td>
+ <td VALIGN=TOP><b>Description</b></td>
+ <td ALIGN=CENTER VALIGN=TOP><b>Required</b></td>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>X</td>
+
+ <td VALIGN=TOP>comma-delimited list of extended (-X...) options,
+ entered without -X
+ (e.g., <code>X="lint"</code> for
+ <code>-Xlint</code>). </td>
+
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+ </tr>
+
+<tr>
+ <td VALIGN=TOP>emacssym</td>
+ <td VALIGN=TOP>Generate symbols for Emacs IDE support
+ (defaults to off)</td>
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+<tr>
+ <td VALIGN=TOP>argfiles</td>
+
+ <td VALIGN=TOP>a comma-delimited list of argfiles that
+ contain a line-delimited list of source file paths
+ (absolute or relative to the argfile)&nbsp;</td>
+
+ <td ALIGN=CENTER VALIGN=TOP>No</td>
+</tr>
+
+</table>
+
+<a name="argfiles"></a>
+<h3>argfiles - Argument list files</h3>
+An argument file is a file (usually <tt>&lt;file&gt;.lst</tt>) containing a list of source file
+paths (absolute or relative to the argfile).
+You can use it to specify all source files to be compiled, which <code>ajc</code> requires
+to avoid searching every possible source file in the source path when building aspects.
+If you specify an argfile to the <tt>ajc</tt> task, it will not include all files in any specified
+source directory (which is the default behavior for the Javac task when no includes are
+specified). Conversely, if you specify excludes, they will be removed from the list of
+files compiled even if they were specified in an argument file.
+
+<br>&nbsp;
+<a name="nestedElements"></a>
+<h3>
+Parameters specified as nested elements</h3>
+This task forms an implicit <a href="http://jakarta.apache.org/ant/manual/CoreTypes/fileset.html">FileSet</a>
+and supports all attributes of <tt>&lt;fileset></tt> (<tt>dir</tt> becomes
+<tt>srcdir</tt>)
+as well as the nested
+<tt>&lt;include></tt>, <tt>&lt;exclude></tt>,
+<tt>&lt;patternset>,
+and &lt;argfile></tt> elements.
+<h4>
+<tt>src</tt>, <tt>classpath</tt>, <tt>bootclasspath</tt> and <tt>extdirs</tt></h4>
+<tt>ajc</tt>'s <i>srcdir</i>, <i>classpath</i>,
+<i>bootclasspath, extdirs</i>
+and <i>jvmarg</i> attributes are <a href="http://jakarta.apache.org/ant/manual/using.html#path">path-like
+structures</a> and can also be set via nested
+<tt>&lt;src></tt>,
+<tt>&lt;classpath></tt>,
+<tt>&lt;bootclasspath>,
+&lt;extdirs> </tt>and <tt>&lt;jvmarg> </tt>elements, respectively.
+<p>
+<h3>
+Examples</h3>
+
+See <a href="../examples/builds.xml">../examples/builds.xml</a>
+for an example build script.
+<p>
+This build script snippet
+
+<pre>&nbsp; &lt;ajc srcdir=&quot;${src}&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; destdir=&quot;${build}&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; argfiles=&quot;demo.lst&quot;
+&nbsp; /&gt;</pre>
+compiles all <tt>.java</tt> files specified in the <tt>demo.lst</tt> and
+stores the <tt>.class</tt> files in the <tt>${build}</tt> directory.&nbsp;
+Unlike the Javac task, the
+<i>includes</i> attribute is empty by default, so only those
+files specified in <tt>demo.lst</tt> are included.
+<p>This next example
+<pre>&nbsp; &lt;ajc srcdir=&quot;${src}&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; destdir=&quot;${build}&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; includes=&quot;spacewar/*,coordination/*&quot;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; excludes=&quot;spacewar/Debug.java&quot;
+&nbsp; /&gt;</pre>
+compiles <tt>.java</tt> files under the <tt>${src}</tt> directory in the
+<tt>spacewar
+</tt>and<tt>
+coordination </tt>packages, and stores the
+<tt>.class</tt> files in the
+<tt>${build}</tt> directory.&nbsp; All source files under
+<tt>spacewar/</tt> and
+<tt>coordination/</tt> are used, except <tt>Debug.java</tt>.
+
+
+<hr>
+</body>
+</html>
diff --git a/docs/dist/doc/ant-tasks.html b/docs/dist/doc/ant-tasks.html
new file mode 100644
index 000000000..f09bbc7e5
--- /dev/null
+++ b/docs/dist/doc/ant-tasks.html
@@ -0,0 +1,230 @@
+<html>
+
+<head>
+<title>AspectJ Ant Tasks</title>
+</head>
+
+<BODY>
+
+<h2 align="center">AspectJ Ant Tasks</h2>
+
+<p align="center"><i>Version @build.version.long@ released on @build.date@.</i></p>
+
+<h3>About the AspectJ Ant tasks</h3>
+
+AspectJ contains a compiler, <tt>ajc</tt>, that can be run from Ant.
+
+Included in the <tt>aspectjtools.jar</tt> are Ant binaries to support
+three ways of running the compiler:
+<ol>
+<li><tt>Ajc10</tt> (<a href="ant-ajc10-task.html">options</a>),
+ a task to run build scripts compatible with the AspectJ 1.0 tasks,</li>
+<li><tt>AjcTask</tt> (<a href="ant-ajc-task.html">options</a>),
+ a task to run the new AspectJ 1.1 compiler, which supports
+ all the eclipse and ajc options, including incremental mode;
+<li><tt>Ajc11CompilerAdapter</tt>,
+ an adapter class to run the new compiler using Javac tasks
+ by setting the build.compiler property.</li>
+</ol>
+
+This describes how to install and use the tasks and the adapter.
+For an example Ant script,
+see <a href="../examples/build.xml">../examples/build.xml</a>.
+
+<h3>Installation</h3>
+<p>Install Jakarta Ant 1.5.1:&nbsp;
+ Please see the official
+ <a href="http://jakarta.apache.org/ant/index.html">Jakarta
+ Ant website</a> for more information and
+ the 1.5.1 <a href="http://jakarta.apache.org/builds/jakarta-ant/release/v1.5.1/bin/">
+ distribution</a>.
+This release is source-compatible with Ant 1.3 and Ant 1.4, but
+the task sources must be
+compiled with those versions of the Ant libraries to be used under those
+versions of Ant. Sources are available under the Common Public License v. 1.0
+at <a href="@aspectj.home.url@">@aspectj.home.url@</a>.
+
+<p>In Ant, third-party tasks can be declared using a <tt>taskdef</tt> entry
+in the build script, to identify the name and classes.
+
+When declaring a task, include the <tt>aspectjtools.jar</tt>
+either in the taskdef classpath
+or in <tt>${ANT_HOME}/lib</tt>
+where it will be added to the system class path by the ant script.
+
+You may specify the task script names directly, or use
+the "resource" attribute to specify the default names:
+<pre>
+ &lt;taskdef
+ resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"&gt;
+</pre>
+The current resource file retains the name "ajc" for the Ajc10 task,
+using "iajc" for the AspectJ 1.1 task.
+This may change in the final release of AspectJ 1.1. <!-- XXX -->
+</p>
+<p>For more information on using Ant, please refer to
+Jakarta's <a href="http://jakarta.apache.org/ant/manual/develop.html">documentation</a>
+on integrating user-defined Ant tasks into builds.</p></li>
+<p>
+
+<h3><a name="#ajc10">Ajc10 (script name: ajc)</a></h3>
+This task handles the same arguments as those used by the AspectJ 1.0 task.
+This should permit those with existing build scripts using
+the Ajc Ant task to continue using the same scripts
+when compiling with 1.1.
+
+This will list any use of options no longer supported
+(e.g., fork, lenient, strict, workingdir, preprocess, usejavac,...),
+and does not provide access to the new features of AspectJ 1.1.
+(Developers using AspectJ 1.1 only should
+upgrade their scripts to use AjcTask instead.)
+<p>
+Following is a declaration for the ajc task and a sample invocation
+that uses the ajc compiler to compile the files listed in
+<tt>default.lst</tt> into the <tt>dest</tt> dir.
+<pre>
+&lt;project name="example" default="compile" &gt
+ &lt;taskdef name="ajc"
+ classname="org.aspectj.tools.ant.taskdefs.Ajc10" &gt;
+ &lt;!-- declare classes needed to run the tasks and tools --&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${home.dir}/tools/aspectj/lib/aspectjtools.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/taskdef&gt;
+
+ &lt;target name="compile" &gt;
+ &lt;mkdir dir="dest" /&gt;
+ &lt;ajc destdir="dest" argfiles="default.lst" &gt;
+ &lt;!-- declare classes needed to compile the target files --&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/ajc&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+<h3><a name="#ajctask">AjcTask (script name: iajc)</a></h3>
+This task handles all the ajc 1.1 compiler options,
+as well as an incremental "tag" file to avoid depending
+on Ant input/output for controlling Ant-based incremenal compilation.
+
+<p>Below is an example of incrementally compiling <tt>src</tt>
+ and <tt>testsrc</tt> root source directories, using <tt>tagfile.txt</tt>
+ to control recompilation and halting.
+When this script is run, the compiler will build once and
+then wait for incremental builds, recompiling each time the
+last-modified date changes on the tag file. When the tag file no longer
+exists, the build will complete. Messages are printed as usual.
+<pre>
+&lt;project name="incremental-example" default="compile" &gt
+ &lt;taskdef
+ resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties"&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${home.dir}/tools/aspectj/lib/aspectjtools.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/taskdef&gt;
+
+ &lt;target name="compile" &gt;
+ &lt;mkdir dir="dest" /&gt;
+ &lt;inc-ajc destdir="dest"
+ tagfile="tagfile.txt"
+ sourceroots="src${path.separator}testsrc" &gt;
+ &lt;!-- declare classes needed to compile the target files --&gt;
+ &lt;classpath&gt;
+ &lt;pathelement location="${home.dir}/tools/aspectj/lib/aspectjrt.jar"/&gt;
+ &lt;/classpath&gt;
+ &lt;/inc-ajc&gt;
+ &lt;/target&gt;
+&lt;/project&gt;
+</pre>
+
+
+<h3><a name="#adapter">Ajc11CompilerAdapter</a></h3>
+This CompilerAdapter can be used in <tt>javac</tt> tasks calls
+by setting the <code>build.compiler</code>
+property to the class name. This enables users to
+to easily switch between Javac and the AspectJ compiler.
+
+To build this way, install <tt>aspectjtools.jar</tt> in <tt>${ANT_HOME}/lib</tt>
+and define the <tt>build.compiler</tt>
+property as the fully-qualified name of the class:
+
+<pre>
+ cp aspectj1.1/lib/aspectjtools.jar ant/lib
+ ant/bin/ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter ...
+</pre>
+
+The AspectJ compiler should run for any compile using the <tt>Javac</tt> task
+(for options, see the Ant documentation for the Javac task).
+
+<p>
+To pass <tt>ajc</tt>-specific arguments, use a <code>compilerarg</code> entry.
+For example,
+
+<pre>
+
+-- command
+
+ Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11BuildCompiler
+
+-- build script
+
+ &lt;property name="ajc"
+ value="org.aspectj.tools.ant.taskdefs.Ajc11BuildCompiler"/>
+
+ &lt;javac srcdir="src" destdir="dest" >
+ &lt;compilerarg compiler="$${ajc}" line="-argfile src/args.lst"/>
+ &lt;javac >
+</pre>
+
+Beware of using regular source lists with this; javac may prune unchanged
+files, which excludes them from the compile process for ajc, which requires
+that all files affected by any aspects be listed explicitly.
+
+<hr>
+
+<h3>4. What to do if you encounter problems</h3>
+<p>If you have problems with the tasks not solved by the documentation,
+please try to see if you have the same problems when running ajc
+directly on the command line.
+<p>
+
+<li>If the problem occurs on the command line also, then the problem is
+not in the task.
+(It may be in the tools; please send bug reports, but only if the code
+is pure-Java.) </li>
+
+
+<li>If the problem does not occur on the command line,
+then it may lie in the parameters you are supplying in Ant or in
+the task's handling of them.</li>
+
+<li>If the build script looks correct and the problem only occurs when building
+from Ant, then please send a report (including your build file, if possible).</li>
+
+<p><b>Known Problems</b>
+<br>For the most up-to-date information on known problems, see the
+ <a href="@aspectj.home.url@/bugs">bug database</a> for
+ <a href="@aspectj.home.url@/bugs/compiler">compiler bugs</a>
+ or <a href="@aspectj.home.url@/ant-support">task bugs</a>.
+
+<li><u>Memory and forking</u>:
+Users email most often about the ajc task running out of memory. This is
+not a problem with the task; some compiles take a lot of memory,
+often more than the same compiles using javac.
+<u>Forking is not supported in this release</u>, so the only solution is to
+increase the memory available to Ant (see the Ant documentation, searching for ANT_OPTS,
+the variable they use in their scripts to pass VM options, e.g., ANT_OPTS=-Xmx128m).
+</li>
+<li><u>Messages suppressed</u>: In the incremental task,
+messages from the compiler are printed but not segregated.
+</li>
+
+<p>
+You can send email to <a href="mailto:users@aspectj.org">users@aspectj.org</a>.
+(Do join the list to participate!) We also welcome any bug reports; you can
+submit them to <a href="@aspectj.home.url@/bugs">@aspectj.home.url@/bugs</a>.
+</body>
+
+</html>
diff --git a/docs/dist/doc/changes.html b/docs/dist/doc/changes.html
new file mode 100644
index 000000000..0d4d304fd
--- /dev/null
+++ b/docs/dist/doc/changes.html
@@ -0,0 +1,1502 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+
+<head>
+<LINK rel="STYLESHEET" href="../style.css" type="text/css">
+<title>AspectJ 1.0.6 Reference -- Recent Changes</title>
+</head>
+
+<body>
+
+<DIV ALIGN=right CLASS=copyrightNotice>
+&copy; Copyright 1998-2002 Palo Alto Research Center Incorporated. All rights reserved.
+</DIV>
+
+<h1>Recent Changes in AspectJ 1.0</h1>
+
+<ul>
+ <li><a href="#1.0.6">1.0.6</a> (released 2002-07-24)
+ <ul>
+ <li><a href="#1.0.6compiler">Compiler</a></li>
+ <li><a href="#1.0.6ajde">AJDE</a></li>
+ <li><a href="#1.0.6ajdoc">Ajdoc</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#1.0.5">1.0.5</a> (released 2002-06-27)
+ </li>
+
+ <li><a href="#1.0.4">1.0.4</a> (released 2002-04-17)
+ </li>
+
+ <li><a href="#1.0.3">1.0.3</a> (released 2002-02-08)
+ </li>
+ <li><a href="#1.0.2">1.0.2</a> (released 2002-02-06)
+ </li>
+ <li><a href="#1.0.1">1.0.1</a> (released 2001-12-18)
+ </li>
+ <li><a href="#1.0.0">1.0.0</a> (released 2001-11-30)
+ </li>
+ <li><a href="#1.0rc3">1.0rc3</a> (released 2001-11-14)
+ </li>
+ <li><a href="#1.0rc2">1.0rc2</a> (released 2001-10-12)
+ </li>
+ <li><a href="#1.0rc1">1.0rc1</a> (released 2001-10-5)
+ </li>
+ <li><a href="#1.0beta1">1.0beta1</a> (released 2001-08-29)
+ </li>
+ <li><a href="#1.0alpha1">1.0alpha1</a> (released 2001-08-09)
+ </li>
+ <li><a href="#oldversions">Previous Versions</a></li>
+ <li><a href="porting.html">Porting and Transition</a></li>
+</ul>
+
+<hr />
+
+<h2><a name="1.0.6">1.0.6</a></h2>
+
+<p> This release contains mainly bug fixes for ajde and ajdoc.
+
+<h3><a name="1.0.6compiler">Compiler</a></h3>
+
+<p>We fixed a bug with switch statements, thanks largely
+to Jason Rimmer's diligence in helping us isolate the problem.
+Also, to help Log4J parse stack traces, we changed class file
+symbolic line references to use [] instead of () for the
+virtual start lines of each file.
+</p>
+
+<h3><a name="1.0.6ajde">AJDE</a></h3>
+
+<p><b>AJDE Framework, AJBrowser, and AJDE for Forte/NetBeans</b></p>
+
+<p>The memory use of the structure model has been streamlined in order to reduce
+footprint when working with large systems.&nbsp; Error tolerance has also been
+improved for dealing with a structure model that is out of synch with resources
+on disk.</p>
+
+<h4>AJDE for JBuilder</h4>
+
+<p>JBuilder 7 is now supported.&nbsp; All known bugs have been fixed including:</p>
+
+<ul>
+ <li><a href="http://aspectj.org/bugs/resolved?id=787">787</a>
+ AJDE for JBuilder throws exception given non-existent file</li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=788">788</a>
+ Label too small in error message </li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=789">789</a>
+ Index-out-of-bounds exception in JBuilder AJDE </li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=792">792</a>
+ Required libraries disappear from JBuilder 6 </li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=795">795</a>
+ Unable to compile open tools </li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=802">802</a>
+ AJDE loses current (cursor) position in file when switching files </li>
+</ul>
+
+<p>In addition, thanks to user feedback that indicated trouble building JBuilder
+OpenTools with AJDE/JBuilder, the OpenTool is now being built with itself. </p>
+
+<h3><a name="1.0.6ajdoc">Ajdoc</a></h3>
+ <ul>
+ <li>Fixed <a href="http://aspectj.org/bugs/resolved?id=790">790</a>
+ aspect code comments suppressed by fix to bug 710
+ </li>
+ <li>Known problems: <a href="http://aspectj.org/bugs/ajdoc">
+ http://aspectj.org/bugs/ajdoc
+ </a></li>
+ </ul>
+
+<hr />
+
+<h2><a name="1.0.5">1.0.5</a></h2>
+
+
+<p>This release includes significant improvements to AspectJ Development
+Environment (AJDE) support. The entire user interface has been revised and
+streamlined. The AJDE features are more tightly integrated into JBuilder and
+NetBeans/Forte support. JBuilder support now includes graphical configuration
+file editing and an integrated AspectJ Browser tool. </p>
+
+<ul>
+ <li><a href="#1.0.5compiler">Compiler</a></li>
+ <li><a href="#1.0.5ajde">AJDE</a></li>
+ <li><a href="#1.0.5ajdoc">Ajdoc</a></li>
+ <li><a href="#1.0.5anttasks">Ant tasks</a></li>
+</ul>
+
+<h3><a name="1.0.5compiler">Compiler</a></h3>
+
+<p> This was another compiler release primarily concerned with fixing
+corner cases in the language implementation. Our handling of nested
+classes, the assert statement, and cflow were the principal offenders
+this time. Thanks to Nicholas Alex Leidenfrost and Patrick Chan for
+their clear and concise bug reports on some of these issues. </p>
+
+<h3><a name="1.0.5ajde">AJDE</a></h3>
+
+<h4><span style="font-weight: 400">This release includes significant
+improvements to AspectJ Development Environment (AJDE) support. All known bugs
+have been fixed, and the core framework quality has been significantly increased
+thanks to the adoption of a unit test suite. The following changes apply
+to all of the AJDE NetBeans/Forte, JBuilder, and the AspectJ Browser support.
+NetBeans/Forte and JBuilder-specific changes are listed below. </span></h4>
+
+
+<ul>
+ <li><span style="font-weight: 400">The entire user interface has been revised
+ and streamlined.</span></li>
+ <li>The structure view and browser have a new UI, and offer both a file-based
+ and global structure views. All views expose node ordering, node
+ filtering, and association filtering functionality. The global views
+ expose a package tree as well as the global inheritance and crosscutting
+ structure. </li>
+ <li>Structure view navigation now has a history exposed by back/forward.</li>
+ <li>The is a new build configuration management UI.</li>
+ <li>The compiler preferences UI now includes access to all build options.</li>
+ <li>Error messages have been improved, and the structure views include
+ annotations of nodes with errors and warnings.</li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+
+<p>Integration into the JBuilder IDE is more streamlined. In addition:</p>
+
+
+<ul>
+ <li>The AspectJ Browser is included as a tool that replaces JBuilder's
+ "Project View" and can be used to navigate the global structure of your system
+ (including the crosscutting and inheritance structure).</li>
+ <li>Inline structure annotations in the editor's gutter can now expose all of
+ the structure presented in the structure view, and can be used to navigate in
+ a similar way. Note that there are preferences for toggling which of
+ these appear.</li>
+ <li>Building is better integrated and the JBuilder build toolbar is removed
+ when AJDE is enabled.</li>
+ <li>Build configurations can be selected from the build button's menu.</li>
+ <li>Execution is better integrated: instead of a separate "run" button
+ JBuilder's run and debug can be used. Note that for new projects you
+ will need to use the "AspectJ Runtime" library, which will be added to your
+ preferences automatically.</li>
+ <li>A new graphical build configuration editor can be used by double-clicking
+ ".lst" files that have been added to the project. </li>
+ <li>Error messages now match JBuilder's look-and-feel and behavior.
+ Seeking to column numbers now works in addition to line numbers.</li>
+</ul>
+
+
+<h4>AJDE for Forte/NetBeans</h4>
+
+
+<p>Integration into the NetBeans IDE is more streamlined. In addition:</p>
+
+
+<ul>
+ <li>NetBeans 3.3.2 and SunONE Studio 4 are supported.</li>
+ <li>Multiple filesystems are supported.</li>
+ <li>Default project build configurations (all project files) are now
+ supported.</li>
+ <li>Build configurations can be selected in the tool bar.</li>
+ <li>Regular NetBeans execution and debugging is supported. Note that you
+ have to add netbeans/lib/ext/aspectjrt.jar file to your project configuration.</li>
+ <li>Class files are generated beside source files (NetBeans/javac default).
+ There is currently no way to specify a target directory.</li>
+</ul>
+
+
+<h4>AJBrowser</h4>
+
+
+<ul>
+ <li>The browser now supports main class execution. Set the main class in
+ the options dialog, and make sure that both the Java executable is on your
+ path, and the class that you expect to execute on your classpath.</li>
+ <li>The error messages UI has been improved.</li>
+</ul>
+
+
+<h3><a name="1.0.5ajdoc">Ajdoc</a></h3>
+<p>Bug fixes:
+</p>
+ <ul>
+ <li><a href="http://aspectj.org/bugs/resolved?id=710">710 -
+ compiler-generated constructor shown with class comment
+ </a></li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=712">712 -
+ comments lost in aspect docs for methods
+ or constructors declared on other types.
+ </a></li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=719">719 -
+ poor support for @link, @see tags
+ </a></li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=742">742 -
+ crash with @see tag
+ </a></li>
+ <li><a href="http://aspectj.org/bugs/resolved?id=751">751 -
+ error loading doclet resource
+ </a></li>
+ </ul>
+
+<h3><a name="1.0.5anttasks">Ant tasks</a></h3>
+<p>Bug fixes:
+</p>
+ <ul>
+ <li><a href="http://aspectj.org/bugs/resolved?id=730">730 -
+ document all supported ajc flags <a></li>
+ </ul>
+
+<hr />
+
+<h2><a name="1.0.4">1.0.4</a></h2>
+
+<ul>
+ <li><a href="#1.0.4compiler">Compiler</a></li>
+ <li><a href="#1.0.4ajde">AJDE</a></li>
+ <li><a href="#1.0.4ajdoc">Ajdoc</a></li>
+ <li><a href="#1.0.4taskdefs">Ant taskdefs</a></li>
+ <li><a href="#1.0.4doc">Documentation</a></li>
+</ul>
+
+<h3><a name="1.0.4compiler">Compiler</a></h3>
+<ul>
+ <li>Over a dozen people independently reported a bug in error
+ handling for the wrong number number of arguments to
+ <code>proceed</code>. This has been turned into a nice error
+ message. A number of other bug reports related to around advice and
+ proceed have also been fixed, including the ability to change the
+ bindings for <code>this</code> and <code>target</code> using proceed
+ in around advice.
+ </li>
+ <li>David Walend gets the <em>black thumb</em> award for the most
+ bug reports submitted by a new user. His bug report on the
+ behavior of after returning advice led to some valuable clarifications
+ of this part of the language spec.
+ </li>
+ <li>A number of places where ajc didn't fully comply with the Java
+ Language Spec have been fixed in this release. Thanks to Neal
+ Gafter for reporting many of these.
+ </li>
+</ul>
+
+<h4>Incompatible changes</h4>
+
+<p>Two potentially surprising incompatible changes have been made to
+ajc in order to bring the compiler into compliance with the 1.0
+language design. These changes will be signalled by clear warning or
+error messages at compile-time and will not cause any run-time
+surprises. We expect most users to never notice these changes.</p>
+
+<ul>
+ <li>The obsolete class
+ <code>org.aspectj.lang.MultipleAspectsBoundException</code> has been
+ removed from aspectjrt.jar. This class had not been used since
+ AspectJ-0.8 and should have been removed prior to the 1.0 release.
+ It is not documented as part of the 1.0 language spec. This change
+ will cause a compile-time type not found error in any code that
+ refers to this exception.</code>
+
+ <li>The compiler was not correctly implementing the AspectJ-1.0
+ language design for some uses of after returning advice. This
+ compiler behavior was fixed, and advice whose behavior might be
+ changed by this bug fix will be highlighted with a compiler
+ warning. More information about some of these changes can be found
+ in the <a href="porting.html#pre-1.0.4">porting notes</a>.</li>
+</ul>
+
+<h3><a name="1.0.4ajde">AJDE</a></h3>
+
+
+<p>This is the first release of AJDE support with significant external
+contribution. A big thanks goes out to Phil Sager for porting the AJDE for
+Forte/NetBeans support to NetBeans 3.3.1 and improving the integration into
+NetBeans.</p>
+
+
+<h4>AJDE for JBuilder</h4>
+
+<ul>
+ <li>Updates<ul>
+ <li>This is a bug fix release only. </li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJDE for Forte/NetBeans</h4>
+
+<ul>
+ <li>Updates<ul>
+ <li>NetBeans 3.3.1 is now supported in addition to NetBeans 3.2 and Forte CE
+ 3.</li>
+ <li>Native NetBeans main class execution can now be used. After doing
+ a "Compile with AJC" browse to the main class in the "Filesystems" Explorer,
+ right-click the class and select "Execute". </li>
+ <li>The debugger can now be used if the project main class is set ("Project"
+ menu -&gt; "Set Project Main Class...").</li>
+ <li>Numerous bugs have been fixed.</li>
+ </ul>
+ </li>
+ <li>Known limitations<ul>
+ <li>Breakpoint setting does not work in the debugger.</li>
+ <li>In the "Filesystems" Explorer red Xs appear on files with AspectJ source
+ code. The "AspectJ" Explorer understands the structure of AspectJ
+ projects and should be used for navigating structure instead.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJDE for Emacs</h4>
+
+
+<ul>
+ <li>This is a bug fix release only.</li>
+</ul>
+
+
+<h3><a name="1.0.4ajdoc">Ajdoc</a></h3>
+<p>Ajdoc now runs under J2SE 1.4, but still requires the tools.jar
+ from J2SE 1.3 be on the classpath.
+</p>
+
+<h3><a name="1.0.4taskdefs">Ant tasks</a></h3>
+<ul>
+ <li>Repackaged to fit into the AspectJ product directory - e.g.,
+ <code>aspectj-ant.jar</code> moved to <code>lib</code>
+ as expected by <code>examples/build.xml</code>.
+ </li>
+ <li>Fixed bugs, esp. <a href="http://aspectj.org/bugs/resolved?id=682">682</a>:
+ Throw BuildException if failonerror and ajdoc detects misconfiguration.
+ </li>
+</ul>
+<h3><a name="1.0.4doc">Documentation</a></h3>
+<p>Added a 1-page quick reference guide. Improved javadoc documentation for
+ the org.aspectj.lang package.
+</p>
+
+
+<hr/>
+
+<h2><a name="1.0.3">1.0.3</a></h2>
+
+<ul>
+ <li><a href="#1.0.3compiler">Compiler</a></li>
+ <li><a href="#1.0.3taskdefs">Ant taskdefs</a></li>
+</ul>
+
+<h3><a name="1.0.3compiler">Compiler</a></h3>
+<p> This release fixes a single significant bug in 1.0.2 where ajc
+could generate unreachable code in <code>-usejavac</code> or
+<code>-preprocess</code> mode. This would happen when around advice
+was placed on void methods whose body consisted solely of a
+<code>while (true) {}</code> loop. We now properly handle the
+flow-analysis for this case and generate code that is acceptable to
+javac. Thanks to Rich Price for reporting this bug.
+</p>
+
+<h3><a name="1.0.3taskdefs">Ant taskdefs</a></h3>
+<p>Added support to the Ajc taskdef for the -source 1.4 and -X options generally.
+</p>
+
+<hr />
+
+<h2><a name="1.0.2">1.0.2</a></h2>
+
+<p> This release is mainly about keeping up with the Joneses. To keep
+up with SUN's release candidate for J2SE1.4, we now officially support
+the new 1.4 assertions and running on the 1.4 VM. In honor of the
+public review of JSR-45 Debugging Support for Other Languages we
+implement this spec for AspectJ. We support Borland's recent release
+of JBuilder 6, and since some of our users are starting to work on Mac
+OSX, AJDE now works nicely on this platform. We also fixed almost all of
+the bugs you reported in 1.0.1.
+</p>
+
+<ul>
+ <li><a href="#1.0.2compiler">Compiler</a></li>
+ <li><a href="#1.0.2ajde">AJDE</a></li>
+ <li><a href="#1.0.2ajdb">AJDB</a></li>
+</ul>
+
+<h3><a name="1.0.2compiler">Compiler</a></h3>
+
+<ul>
+ <li>Official support for <code>-source 1.4</code> option to compile new
+ <a href="http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html">1.4 assertions</a>.
+ This makes ajc completely compatible with j2se-1.4.
+ </li>
+ <li>Implementation of <a href="http://jcp.org/jsr/detail/45.jsp">
+ JSR-45 Debugging Support for Other Languages</a> so that debuggers which
+ correctly implement this specification will be able to accurately debug
+ any AspectJ program at a source code level. We are not currently
+ aware of any debuggers that implement this so far, but expect that
+ as j2se-1.4 becomes widely available this will change.
+ </li>
+ <li>As proposed by Arno Schmidmeier and seconded by Nick Lesiecki, we now have an
+ experimental <code>-Xlint</code> option that will provide warnings when
+ type patterns used in pcds have no bindings. We are very interested in
+ feedback on the usefulness and suggested improvements for this feature.
+ </li>
+ <li>Several significant bugs in the implementation of around advice have been fixed.
+ These include issues with <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=632">
+ dynamic tests</a>, with
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=620">
+ complicated local types in an around body</a>, and with
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=636">
+ capturing proceed in a closure</a>.
+ </li>
+ <li>All but two (<a href="http://aspectj.org/jitterbug/aspectj-bugs/compiler?id=626">1</a>,
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/compiler?id=645">2</a>)
+ verified bugs in 1.0.1 have been fixed. The two outstanding bugs
+ have relatively easy work-arounds. Thanks as usual to everyone who
+ submitted a bug report.
+ </li>
+ <li>We no longer use the <code>SYNTHETIC</code> attribute to label declarations
+ added by the aspectj compiler. We were using this attribute in compliance
+ with <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#80128">
+ the JVM Specification</a>; however, we've found that many tools expect
+ this attribute to only be used for the narrow purpose of implementing
+ Java's inner classes and that using it for other synthetic members can confuse
+ them. This led to problems both
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=649">with javap</a> and
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=646">with javac</a>.
+ </li>
+ <li>Changes required adding runtime classes, so please compile and run using the latest
+ <code>aspectjrt.jar</code>
+ </li>
+
+</ul>
+
+<h3><a name="1.0.2ajde">AJDE</a></h3>
+
+<p align="left">This is a bug fix release only. </p>
+
+<ul>
+ <li>
+
+<p align="left">Thanks to Dave Yost and Matt Drance for submitting the AJDE
+patches for Mac OSX (context popup menus and keyboard shortcuts did not work). </p>
+
+ </li>
+ <li>
+
+<p align="left">Bugs in history navigation (back-forward buttons in the
+structure view) have been fixed.</p>
+
+ </li>
+ <li>
+
+<p align="left">"Declares" are now handled properly in the structure view.</p>
+
+ </li>
+ <li>
+
+<p align="left">Other GUI and usability improvements have been made the AspectJ
+Browser and core framework.</p>
+
+ </li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+
+<ul>
+ <li>Support has been extended to JBuilder 6, and support for Enterprise
+ version features has been improved.</li>
+ <li>Fixed bug causing inline source code annotations in the editor pane to not
+ be updated after a recompile.</li>
+ <li>Keyboard shortcuts were fixed to work with Mac OSX.</li>
+</ul>
+
+
+<h4>AJDE for Forte</h4>
+
+
+<ul>
+ <li>Keyboard shortcuts were fixed to work with Mac OSX.</li>
+</ul>
+
+<h4><a name="1.0.2ajdb">AJDB</a></h4>
+
+<p> Some minor bug fixes, but this is still early-access software.
+ Please try using another JPDA-compliant debugger. If it uses
+ JDI correctly, then it should navigate to line numbers
+ when the classes are run under J2SE1.4, based on
+ the new JSR-45 debugging support described above.
+ We would appreciate any reports of success or failure.
+</p>
+
+<hr />
+
+<h2><a name="1.0.1">1.0.1</a></h2>
+
+<ul>
+ <li><a href="#1.0.1compiler">Compiler</a></li>
+ <li><a href="#1.0.1ajde">AJDE</a></li>
+ <li><a href="#1.0.1ajdb">AJDB</a></li>
+</ul>
+
+<h3><a name="1.0.1compiler">Compiler</a></h3>
+
+<p> This release fixes a significant performance issue in the
+compiler, reported by Rich Price, that could lead to extremely long
+compiles in systems with many aspects and classes. Several other
+small bugs related to reporting compilation errors have also been
+fixed, see <a
+href=http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=610>this
+bug report</a> for an example.
+</p>
+
+<p> A new experimental flag has been added,
+<code>-XaddSafePrefix</code>, that will cause the prefix
+<code>aspectj$</code> to be inserted in front of all methods generated
+by ajc. This mode should be helpful when using aspectj with tools
+that do reflection based on method names, such as EJB tools. Thanks
+to Vincent Massol for pointing out the importance of this. It is
+expected that this prefix will either become the default compiler
+behavior in the future or a non-experimental flag will replace it.
+</p>
+
+
+<h3><a name="1.0.1ajde">AJDE</a></h3>
+
+<p align="left">Minor bug fixes, including: AJDE for JBuilder failed to preserve
+application parameters from project settings when executing the application.</p>
+
+<p align="left">Source builds were cleaned up for JBuilder and Forte sources.</p>
+
+<h3><a name="1.0.1ajdb">AJDB</a></h3>
+
+<p>Two bugs were reported and have been fixed in this release.
+ (Note that ajdb is still considered early-access software.)</p>
+
+<ul>
+ <li>bug 611: NullPointerException dumping non-primitive values</li>
+ <li>bug 617: -X and -D options not passed to debug VM correctly</li>
+</ul>
+
+<h2><a name="1.0.0">1.0.0</a></h2>
+
+<ul>
+ <li><a href="#1.0.0language">Language</a></li>
+ <li><a href="#1.0.0compiler">Compiler</a></li>
+ <li><a href="#1.0.0ajde">AJDE</a></li>
+ <li><a href="#1.0.0ajdoc">AJDoc</a></li>
+ <li><a href="#1.0.0taskdefs">Ant taskdefs</a></li>
+</ul>
+
+<h2><a name="1.0.0language">Language</a></h2>
+
+<p>There were no language changes for this release.</p>
+
+<h2><a name="1.0.0compiler">Compiler</a></h2>
+
+<p>Several minor bugs primarily in error handling were reported and
+have been fixed in this release. The two most serious bugs are
+described below:</p>
+
+<ul>
+ <li>Niall Smart and Stephan Schmidt reported related bugs (variants
+ of which are also produced by other compilers) that caused verify
+ errors when dealing with nested try-finally and synchronized
+ statements. These are now fixed. More details are available
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=601">
+ here</a> and
+ <a href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=595">
+ here</a>
+ </li>
+
+ <li>Jan Hannemann submitted a <a
+ href="http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=600">
+ succint and clear bug report</a> for a difficult intermittant bug.
+ The bug led to the compiler sometimes generating illegal code when
+ introduced methods on a class overrode introduced methods on an
+ interface implemented by that class. This is now fixed.</li> </ul>
+
+<h2><a name="1.0.0ajde">AJDE</a></h2>
+
+<p align="left">Numerous user interface refinements were made to the browser and
+core AJDE functionality. Error handling and reporting has been improved.
+All of the AJDE tools now support the ".aj" file extension.</p>
+
+<h4>AJDE for JBuilder</h4>
+
+
+<ul>
+ <li>The AspectJ Browser now uses JBuilder's icons and distinguishes nodes by
+ visibility.</li>
+ <li>Project-setting VM parameters are now supported by the "AJDE Run" button.</li>
+</ul>
+
+
+<h4>AJDE for Forte</h4>
+
+
+<ul>
+ <li>The AspectJ Browser now uses Forte's icons and distinguishes nodes by
+ visibility</li>
+</ul>
+
+
+<h4>AJBrowser</h4>
+
+
+<ul>
+ <li>Documentation for the browser is now available at
+ <a href="http://aspectj.org/docs">http://aspectj.org/docs</a> </li>
+</ul>
+
+
+<h4>Emacs Support: aspectj-mode and AJDEE</h4>
+
+<ul>
+ <li>Improved updating of annotations during editing.</li>
+ <li>Pop-up jump menu now placed (with mouse pointer) near cursor.</li>
+ <li>[AJDEE only] Improved filtering of legal code completions.</li>
+</ul>
+
+<h4><a name="1.0.0ajdoc">AJDoc</a></h4>
+
+<ul>
+ <li>Runs only in J2SE 1.3 - not 1.2 or 1.4.
+ You can document 1.x-reliant programs by using the options
+ to compile using 1.x libraries.</li>
+ <li>Disabled some non-functioning options, documented as
+ <code>unsupported</code> in the syntax message.</li>
+</ul>
+
+<h4><a name="1.0.0taskdefs">Ant taskdefs</a></h4>
+<ul>
+ <li>Fork is not supported in the AJDoc taskdef</li>
+</ul>
+
+<h2><a name="1.0rc3">1.0rc3</a></h2>
+
+<h2><a name="1.0rc3language">Language</a></h2>
+
+<p>There have been several minor clarifications/changes to the
+language.</p>
+
+<ul>
+ <li>Thanks to Robin Green for suggesting that we could relax the
+ rules for inheriting multiple concrete members in order to allow
+ those unambiguous cases where one member has already overridden the
+ other. <a href=http://aspectj.org/pipermail/users/2001/001289.html>
+ More details...</a></li>
+
+ <li>Ron Bodkin encouraged us to examine the details of privileged
+ aspects more closely. This led to several small improvements and
+ clarifications to this language feature.
+ <a href=http://aspectj.org/pipermail/users/2001/001258.html> More
+ details...</a></li>
+</ul>
+
+<h2><a name="1.0rc3compiler">Compiler</a></h2>
+
+<p>This release saw several changes to the compiler in order to
+work-around known bugs in different JVMs, or to otherwise mimic the
+behavior of javac rather than necessarily following the Java Language
+Specification.</p>
+
+<ul>
+ <li>Hanson Char reported a bug where ajc's correctly generated
+ bytecodes for some references to interface fields result in verify
+ errors on certain JVMs. While this is a known bug in those JVMs,
+ we've modified ajc to be bug compatible with all the other Java
+ compilers out there to work-around this JVM bug.
+ <a href=http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=551>
+ More details...</a></li>
+
+ <li>Frank Hunleth discovered a similar bug where ajc's correct
+ bytecodes could lead to essentially random method dispath due to a
+ bad bug in the 1.3.0 JVM from Sun. Even though this bug was fixed
+ in the 1.3.1 and 1.2.2 JVMs, we have introduced the appropriate
+ work-around in ajc's code generation. <a
+ href=http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=580>More
+ details...</a></li>
+
+ <li>Thomas Haug (as well as several other members of his group)
+ reported a problem with name binding where ajc was behaving
+ differently than javac. This problem was resolved to come from a
+ class created by an obfuscator that conflicted with his package
+ names. The JLS doesn't clearly specify which of these two behaviors
+ is correct. Nevertheless, ajc has been changed to treat packages
+ more like javac does in order to minimize this sort of problem in
+ the future. <a
+ href=http://aspectj.org/jitterbug/aspectj-bugs/resolved?id=574> More
+ details...</a></li>
+
+ <li>Several "real" bugs in ajc were also reported and fixed. Toby
+ Allsopp gets credit for reporting two of them. The most interesting
+ of these bugs to me was his report that we just didn't support
+ qualified anonymous inner constructors. This is a part of the Java
+ language that ajc has never supported over its almost 3 year
+ history. We'd just noticed this ourselves when running the jacks
+ compiler test suite from the jikes group, and had added the feature
+ days before getting our first bug report for it not being
+ there.</li>
+</ul>
+
+<h2><a name="1.0rc3ajde">AJDE</a></h2>
+
+<ul>
+ <li>The structure view has been improved. </li>
+ <li>Multiple user-configurable views are supported.</li>
+ <li>Structure tree filtering and ordering has been added. </li>
+ <li>A split tree mode has been added to permit the navigation of multiple
+ views on the same structure. </li>
+ <li>The view can also be toggled between a file-based and a system-based mode
+ which determines whether the root of the structure tree is the current file or
+ the project root. </li>
+ <li>The signatures of tree nodes have been improved and several new node
+ associations are now navigable. </li>
+ <li>A depth slider for controlling tree-expansion has been added.</li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+
+<ul>
+ <li>Changes:</li>
+ <li>Inline annotations support have been improved and made consistent with the
+ structure tree (annotations only show up for intra-declaration structure).</li>
+ <li>The current structure view persists across IDE launches.</li>
+ <li>An enabled AJDE no longer slows down JBuilder shutdown.</li>
+</ul>
+
+
+<h4>AJDE for Forte</h4>
+
+
+<ul>
+ <li>Execution remembers main class.</li>
+ <li>The bug causing an error during a "Mode" and "Explorer" switch has been
+ fixed.</li>
+</ul>
+
+
+<h4>AJBrowser</h4>
+
+
+<ul>
+ <li>AJBrowser is currently an undocumented demonstration application. To use
+ it type: ajbrowser &lt;lst file1&gt; &lt;lst file2&gt; ...</li>
+ <li>Multiple source locations can be shown by selecting multiple nodes and
+ right-clicking to select the "Display Sources" command.</li>
+</ul>
+
+
+<h4>Emacs Support: aspectj-mode and AJDEE</h4>
+
+<ul>
+ <li>Numerous jump-menu improvements, including operation of pop-ups.</li>
+ <li>For AJDEE, compatibility with JDEE 2.2.9beta4. Also, fixes in completion,
+ ajdoc launch, and speedbar.</li>
+</ul>
+
+<h3><a name="1.0rc3ajdoc">AJDoc</a></h3>
+
+<p>Some of the more obvious NullPointerException bugs in Ajdoc were fixed, but
+Ajdoc does not implement all the functionality of Javadoc and has some bugs:</p>
+<ul>
+ <li>Split indexes do not work correctly</li>
+ <li>Inner classes are not listed in indexes </li>
+ <li>Synthetic methods are documented</li>
+ <li>There is no package frame even when packages are specified on the command line</li>
+ <li>-group option is not implemented</li>
+ <li>-use targets are not all calculated correctly</li>
+ <li>Exception information may not be printed for the @throws tag</li>
+ <li>Verbose output should go to stderr, not stdout</li>
+ <li>Extra links are generated (should be unlinked text) </li>
+</ul>
+<p>Further, Ajdoc has not been testing on variants of the J2SE (it uses javadoc classes).
+
+<h3><a name="1.0rc3taskdefs">Ant taskdefs</a></h3>
+<p>The Ajc taskdef was updated to support the new compiler options and the .aj extension,
+and some NullPointerException bugs were fixed (thanks to Vincent Massol for a bug
+report listing the line number of the fix). The AJDoc cannot be run repeatedly
+in a single Ant run, and has trouble loading the doclet unless the libraries
+are installed in ${ant.home}/lib.
+<p>
+<hr />
+<h2><a name="1.0rc2">1.0rc2</a></h2>
+
+ <ul>
+ <li><a href="#1.0rc2language">Language</a></li>
+ <li><a href="#1.0rc2compiler">Compiler</a></li>
+ <li><a href="#1.0rc2ajde">AJDE</a></li>
+ </ul>
+
+<h2><a name="1.0rc2language">Language</a></h2>
+
+<p>There are no language changes in this release. This is a bug fix release
+only.</p>
+
+<h2><a name="1.0rc2compiler">Compiler</a></h2>
+
+<p>A bug in handling inner type names that conflict with enclosing
+type names was fixed. Many error messages were improved.</p>
+
+<h2><a name="1.0rc2ajde">AJDE</a></h2>
+
+<ul>
+ <li>This is a bug fix release only.</li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>Fixed bug causing the output path to be ignored and .class files to be
+ generated into the JBuilder install's "bin" directory.</li>
+ <li>Fixed bugs in Browser listener causing NullPointerExceptions to be thrown
+ if no node editor was present.</li>
+ <li>Fixed bug permitting "-bcg" option to be passed to the compiler.</li>
+ <li>Fixed bug preventing ajc from compiling all of the project source files
+ when automatic package discovery was on (JBuilder Proffessional and Enterprise
+ editions).</li>
+ <li>If the "-preprocess" flag is used resulting source files will be placed in
+ the project's "Working directory".</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>"Automatic package discovery" mode is not supported in this release.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJDE for Forte</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>Moved the "AspectJ" menu into the "Tools" menu in order to make it less
+ intrusive.</li>
+ <li>Added a "ctrl-alt-shift-F9" keyboard compile shortcut.</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>Known bug: "Mode" switching is not supported in this version--you must
+ do all of your AspectJ work in the "Editing" mode. If you switch modes the
+ IDE has to be restarted for the AspectJ window to show again. Switching to a
+ different tab in the ProjectExplorer has the same effect.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJBrowser</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>...</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>AJBrowser is currently an undocumented demonstration application. To use
+ it type:<br>
+ &gt; ajbrowser &lt;lst file1&gt; &lt;lst file2&gt; ...</li>
+</ul>
+
+ </li>
+</ul>
+
+<h4>Emacs Support: aspectj-mode and AJDEE</h4>
+
+<p align="left"> This release now properly displays annotations for call sites and
+ introductions. Robustness has been improved in several dimensions,
+ including performance at startup. The compile menu now recomputes
+ properly when changing directories.</p>
+
+<hr />
+
+<h2><a name="1.0rc1">1.0rc1</a></h2>
+
+ <ul>
+ <li><a href="#1.0rc1language">Language</a></li>
+ <li><a href="#1.0rc1compiler">Compiler</a></li>
+ <li><a href="#1.0rc1ajde">AJDE</a></li>
+ </ul>
+
+<h2><a name="1.0rc1language">Language</a></h2>
+
+<p>Some of the details of the specification for perthis and pertarget
+have changed. These changes make these language constructs
+implementable on current JVMs without memory leaks (this wasn't true
+of the previous version). Most people will probably not notice these
+changes, but the correct semantics are described in
+<a href="progguide/apb.html">the semantics section of the programming
+guide</a>.
+</p>
+
+<p>In a related change, aspects are not allowed to implement either
+the <code>java.io.Serializable</code> or the
+<code>java.lang.Cloneable</code> interface. It is unclear what the
+correct behavior of a system should be when an aspect is serialized or
+cloned, and rather than make an arbitrary choice right now we've
+chosen to leave the most room to design them right in a future
+release.</p>
+
+<h2><a name="1.0rc1compiler">Compiler</a></h2>
+
+<p>ajc now directly generates .class files without using javac as a
+back-end. This should result in improved compiler performance, better
+error messages and better stack-traces and debugging info in those
+.class files. -preprocess mode is still available for those who want
+to generate legal Java source code and a new -usejavac mode is
+available if you have a requirement to continue to use javac as a
+back-end.</p>
+
+<p>ajc now officially supports source files with the .aj extension.
+We plan to extend this support to the rest of our tools as time
+permits.
+</p>
+
+<p>This release of ajc includes support for the "-source 1.4" option
+that enables the new 'assert' keyword in jdk1.4. This option only
+works correctly when compiling against the jdk1.4 libraries. In
+addition, this release of ajc will run under SUN's jdk1.4beta2.
+However, we still strongly recommend that most users use the non-beta
+jdk1.3.</p>
+
+<h2><a name="1.0rc1ajde">AJDE</a></h2>
+
+<ul>
+ <li>The structure view can now be configured (using the "Options" dialog) to
+ display different kinds of associations between program elements that appear
+ in the tree.</li>
+ <li>Structure view history navigation has been added. </li>
+ <li>When navigating links the structure view will stay synchronized with the
+ editor.</li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>Inline structural navigation annotations appear in the gutter of the
+ editor and can be used to navigate associations such as advice and
+ introduction.</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>"Automatic package discovery" mode is not supported in this release.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJDE for Forte</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>Support for Forte 3 and Netbeans 3.2 has been added.</li>
+ <li>The module is now installed by default on the first use without having to
+ go to the IDE options to enable it.</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>Known bug: "Mode" switching is not supported in this version--you must
+ do all of your AspectJ work in the "Editing" mode. If you switch modes the
+ IDE has to be restarted for the AspectJ window to show again. Switching to a
+ different tab in the ProjectExplorer has the same effect.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJBrowser</h4>
+
+<ul>
+ <li>Changes:<ul>
+ <li>Build configuration file editor added.</li>
+</ul>
+
+ </li>
+ <li>Limitations:<ul>
+ <li>AJBrowser is currently an undocumented demonstration application. To use
+ it type:<br>
+ &gt; ajbrowser &lt;lst file1&gt; &lt;lst file2&gt; ...</li>
+</ul>
+
+ </li>
+</ul>
+
+<h4>Aspectj-mode and AJDEE: AspectJ support in Emacs</h4>
+
+<p align="left">This release of AspectJ support for Emacs includes corrections to the
+documentation and the appearance of annotations and jumps in the editing
+view. Also, advice are now shown on non-declarations, when appropriate,
+such as call advice. The internal event model has been revised to reduce
+computational overhead. </p>
+
+<hr />
+
+<h2><a name="1.0beta1">1.0beta1</a></h2>
+
+<ul>
+ <li><a href="#1.0beta1language">Language</a></li>
+ <li><a href="#1.0beta1compiler">Compiler</a></li>
+ <li><a href="#1.0beta1ajbrowser">AJBrowser</a></li>
+ <li><a href="#1.0beta1ajde">AJDE</a></li>
+</ul>
+
+<h2><a name="1.0beta1language">Language</a></h2>
+
+<p>There is one language change since 1.0alpha1. The static modifier is
+no longer needed or allowed on pointcut declarations. Name binding
+for pointcut declarations works like class methods now. Thanks to
+Robin Green for encouraging us to look at this one last time.</p>
+
+<p>The current implementation of perthis/pertarget has the possibility of
+memory leaks (thanks to Arno Schmidmeier for pointing this out). The
+design of this part of the language will almost certainly see some
+changes in the next release to address issues of implementability on
+the JVM as well as related issues.</p>
+
+<h2><a name="1.0beta1compiler">Compiler</a></h2>
+
+<p>The ajc compiler should now catch all errors in source code and you
+should no longer see errors coming from files in 'ajworkingdir'.
+Please report any errors in 'ajworkingdir' as bugs.</p>
+
+<p>All reported bugs in 1.0alpha1 have been fixed. Thanks to everyone
+for your bug reports. Most notably, the 'if' pcd that was added in
+1.0alpha1 should work correctly in this release. Thanks to Morgan
+Deters for a very thorough bug report on this broken feature days
+after the 1.0alpha1 release.</p>
+
+<h2><a name="1.0beta1ajbrowser">AJBrowser</a></h2>
+
+<ul>
+ <li>Support for executing classes has been added.</li>
+ <li>.lst can now be passed as arguments on the command line.</li>
+ <li>Compiler options can be set.</li>
+ <li>Know limitations:<ul>
+ <li>In order to execute classes they must be available on the classpath that
+ the browser is launched with.</li>
+ </ul>
+ </li>
+</ul>
+
+<h2><a name="1.0beta1ajde">AJDE</a></h2>
+
+<ul>
+ <li>The performance and UI of the structure tree has been improved.</li>
+ <li>Compilation now runs in a separate thread and a progress monitor is
+ updated during the compile.</li>
+ <li>The structure view now persists across IDE launches.</li>
+ <li>Limitations:<ul>
+ <li>If an error occurs in the javac pass it will not display properly in the
+ error messages pane. To view the error you have check the output of the
+ console that the IDE was launched from. No more errors should be passed
+ to javac, so please report this behavior and the corresponding error message
+ as a bug.</li>
+</ul>
+
+ </li>
+</ul>
+
+<h4>AJDE for JBuilder</h4>
+
+<ul>
+ <li>Known bugs have been fixed.</li>
+ <li>Classpath separator character is no longer hardcoded.</li>
+ <li>Keyboard shortcuts for compilation (ctrl-F11) and execution (ctrl-F12)
+ have been added.</li>
+ <li>Limitations:<ul>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>AJDE for Forte</h4>
+
+<ul>
+ <li>Known bugs have been fixed.</li>
+ <li>Limitations:<ul>
+ <li>"Mode" switching is not supported in this version--you must do all of your
+ AspectJ work in the "Editing" mode. If you switch modes the IDE has to
+ be restarted for the AspectJ window to show again.</li>
+ <li>There are no keyboard compile/execute shortcuts.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ </ul>
+ </li>
+</ul>
+
+<h4>Aspectj-mode and AJDEE: AspectJ support in Emacs</h4>
+
+<p> AspectJ Development Environment for Emacs has been split into two pieces,
+aspectj-mode (an extension of java-mode), and AJDEE (an extension of JDE).
+Additionally, a switch, -emacssym, has been added to ajc that generates
+AspectJ declarations information directly, thus beanshell is no longer
+required for use of these modes.
+</p>
+
+<hr />
+
+<h2><a name="1.0alpha1">1.0alpha1</a></h2>
+
+<p> This is the first alpha release of the 1.0 language and tools.
+There have been many changes in the language, and many improvements to
+the tools. We wish to thank our users for putting up with the high
+volatility of AspectJ in the push to 1.0. </p>
+
+ <ul>
+ <li><a href="#1.0alpha1language">Language</a></li>
+ <li><a href="#1.0alpha1compiler">Compiler</a></li>
+ <li><a href="#1.0alpha1documentation">Documentation</a></li>
+ <li><a href="#1.0alpha1ajdoc">AJDoc</a></li>
+ <li><a href="#1.0alpha1ant">Ant</a></li>
+ <li><a href="#1.0alpha1ajbrowser">AJBrowser</a></li>
+ <li><a href="#1.0alpha1ajde">AJDE</a></li>
+ </ul>
+
+<h3><a name="1.0alpha1language">Language</a></h3>
+
+<p> There have been many changes to make the 1.0 language both simpler
+and more powerful. User feedback has driven most of these design
+changes. Each email we've received either making a suggestion or just
+asking a question about a confusing part of the language has played a
+part in shaping this design. We'd like to thank all of our users for
+their contributions.
+
+<p>While we don't have room to thank all of our users by name, we'd
+like to specifically mention a few people for their high-quality
+sustained contributions to the users@aspectj.org mailing list as well
+as through their feature requests and bug reports. Robin Green
+(who'll be very happy to see <code>declare error</code>), Stefan
+Hanenberg (who should appreciate the '+' wildcard in type patterns),
+and Rich Price (who suggested final pointcuts, more flexible
+dominates, and many other improvements).<p>
+
+<p> Note that entries into the <a href="porting.html">porting
+notes</a> for this release are linked from the various language
+changes. </p>
+
+<h4>Pointcuts</h4>
+
+<p> Perhaps the least interesting -- but most pervasive -- change is
+that the names of the single-kinded pointcut designators (the ones
+that pick out only one kind of join point) </p>
+
+<blockquote>calls executions gets sets handlers initializations
+staticinitializations</blockquote>
+
+<p> have been
+<a href="porting.html#1.0a1-plural-to-singular">changed</a> to be
+singular rather than plural nouns </p>
+
+<blockquote>call execution get set handler initialization
+staticinitialization</blockquote>
+
+<p> Although a side benefit is that the names are one character
+shorter, the real benefit is that their combination with the
+<CODE>&amp;&amp;</CODE> and <code>||</code> operators now reads much
+more naturally. No longer does "and" mean "or" and "or" mean "and".
+</p>
+
+<p> You'll notice that <code>receptions</code> doesn't appear on the
+table as being shortened to <code>reception</code>. That's because
+call and reception join points have been merged, and the
+<code>receptions</code> pointcut declaration has been
+<a href="porting.html#1.0a1-remove-receptions">eliminated</a>. Now,
+<code>call</code> join points describe the action of making a call,
+including both the caller and callee. Eliminating reception join
+points makes AspectJ much simpler to understand (reception join points
+were a commonly misunderstood feature) without giving up expressive
+power.</p>
+
+<p> We have <a href="porting.html#1.0a1-fixing-state-access">changed
+the mechanism for accessing state</a> at join points, which has the
+benefit of making our treatment of signatures
+<a href="porting.html#1.0a1-no-subs-in-sigs">cleaner</a> and easier to
+read. As a part of this, the <code>instanceof</code> pointcut
+designator has now been
+<a href="porting.html#1.0a1-fixing-instanceof">split into two
+different pointcut designators</a>, <code>this</code> and
+<code>target</code>, corresponding to a join point's currently
+executing object and target object, respectively. </p>
+
+<p> The new <code>args</code> pointcut adds expressive power to the
+language by allowing you to capture join points based on the actual
+type of an argument, rather than the declared type of its formal. So
+even though the <code>HashSet.removeAll</code> method takes a
+<code>Collection</code> as an argument, you can write advice that only
+runs when it is actually passed a <code>HashSet</code> object. </p>
+
+<p> AspectJ's notion of object construction and initialization, a
+complicated process in Java, has been clarified. This affects some
+uses of the
+<a href="porting.html#1.0a1-initializations">initializations
+pointcut</a> and
+<a href="porting.html#1.0a1-constructor-calls">constructor calls</a>
+pointcut. </p>
+
+<p> The little-used pointcuts
+<a href="porting.html#1.0a1-hasaspect"><code>hasaspect</code></a> and
+<a href="porting.html#1.0a1-withinall"><code>withinall</code></a> have
+been removed. </p>
+
+<p> The <code>returns</code> keyword is
+<a href="porting.html#1.0a1-user-defined-returns">no longer
+necessary</a> for user-defined pointcuts. </p>
+
+<p> Pointcuts may now be declared <code>static</code>, and
+<a href="porting.html#1.0a1-static-pointcuts">only static
+pointcuts</a> may be declared in classes and referred to with
+qualified references (such as <code>MyAspect.move()</code>). </p>
+
+<p> Non-abstract pointcuts may now be declared <code>final</code>.
+</p>
+
+<p> We have finally added an extremely general pointcut,
+<code>if(<var>BooleanExpression</var>)</code>, that picks out
+join points programatically. </p>
+
+
+<h4>Type patterns</h4>
+
+<p> Our treatment of
+<a href="porting.html#1.0a1-new-wildcards">* and ..</a> in type
+patterns is cleaner. </p>
+
+<p> Type patterns now have the ability to include array types, and
+there is a new wildcard, +, to pick out all subtypes of a given type.
+Previously, the subtypes operator was only allowed in introduction,
+and was <a href="porting.html#1.0a1-subtypes-to-plus">spelled
+differently</a>. </p>
+
+<h4>Advice</h4>
+
+<p> Around advice is treated much more like a method, with a
+<a href="porting.html#1.0a1-around-returns">return value</a> and an
+optional <a href="porting.html#1.0a1-around-throws">throws clause</a>.
+</p>
+
+<p> The advice precedence rules have been
+<a href="porting.html#1.0a1-advice-precedence">changed</a>. Now, for
+example, a piece of after advice that appears lexically later than
+another piece of after advice will run later, as well. Previously,
+the relationship was the other way around, which caused no small
+amount of confusion. </p>
+
+<p> After returning advice has lost a
+<a href="porting.html#1.0a1-after-returning">useless set of
+parentheses</a> when not using the return value. </p>
+
+<p> The <code>thisStaticJoinPoint</code> reflective object has been
+<a href="porting.html#1.0a1-this-static-join-point">renamed</a>, and
+the <code>thisJoinPoint</code> object hierarchy has been
+<a href="porting.html#1.0a1-this-join-point">simplified</a>. </p>
+
+<h4>Introduction and static crosscutting</h4>
+
+<p> On the static side of the language, introduction hasn't changed,
+but there is now a new keyword, <code>declare</code>, that is used to
+declare various statically-crosscutting properties. One of these
+properties is subtyping, so we've
+<a href="porting.html#1.0a1-plus-implements-extends">gotten rid of</a>
+the ugly keywords <code>+implements</code> and
+<code>+extends</code>. </p>
+
+<p> We have provided two new forms, <code>declare error</code> and
+<code>declare warning</code>, for the often-asked-for property of
+compile-time error detection based on crosscutting properties. </p>
+
+<p> AspectJ's interaction with checked exceptions is now firmly on the
+side of static crosscutting, since Java treats such exceptions at
+compile-time. A new form, <code>declare soft</code>, can be used to
+"soften" checked exceptions into an unchecked form. This may affect
+some uses of <a href="porting.html#1.0a1-now-use-soft">around
+advice</a> that previously mucked with the exception checking
+system.</p>
+
+<h4>Aspects</h4>
+
+<p> The "of each" modifiers have been
+<a href="porting.html#1.0a1-aspects">renamed</a>. Apart from the
+spelling, the main interesting difference is the splitting up of
+<code>of eachobject</code> into two different modifiers, parallel with
+the split of <code>instanceof</code> into <code>this</code> and
+<code>target</code>. </p>
+
+<p> The <code>dominates</code> keyword now takes a type pattern,
+rather than a type. This allows an aspect A, for example, to declare
+that its advice should dominate the advice of another aspect B as well
+as its subtypes, with the new + subtypes operator: <code>aspect A
+dominates B+</code>.
+</p>
+
+<h3><a name="1.0alpha1compiler">Compiler</a></h3>
+
+<p> The most important change in the compiler is that it supports the
+new language. In addition, all reported bugs in the last release have
+been fixed. Thanks for your bug reports.</p>
+
+<p>The compiler also gets a new <code>-encoding</code> flag in this
+release for handling source files that are not in standard US-ASCII
+format. Thanks to Nakamura Tadashi for both suggesting this feature
+and for submitting a nice patch to implement it.
+
+<h4>Known Limitations</h4>
+
+<p> The previous compiler's limitations regarding join points that
+occurred in anonymous classes have all been eliminated.
+Unfortunately, eliminating this restriction has resulted in
+preprocessed source code that is less readable than in previous
+releases. More care will be taken in the next release to mitigate
+this effect. </p>
+
+<p> Many semantic errors are not caught by ajc but fall through to
+javac. Moreover, some errors regarding the initialization of final
+fields might never show up when using ajc. This will be fixed
+shortly. </p>
+
+
+<h3><a name="1.0alpha1documentation">Documentation</a></h3>
+
+<p> Although we spent much of our time this release cycle updating the
+documentation to the new language rather than improving its content,
+we did make some structural improvements. The old <cite>Primer</cite> has been
+split into a <cite>Programming Guide</cite>, covering the language, and a
+<cite>Development Environment Guide</cite>, covering the develompent tools. In
+addition, printable versions of both guides (in PDF) are finally
+included in the documentation package. </p>
+
+<h3><a NAME="1.0alpha1ajdoc">Ajdoc</a></h3>
+
+<p> Ajdoc was rewritten to conform with the language changes and provide support
+for other AspectJ/Java compilers. Our doclet is used by default creating
+AspectJ-specific documentation, or Sun's standard doclet can be used by
+passing the '-standard' flag to Ajdoc to produce regular Javadoc documentation
+(excluding AspectJ-specifics).
+</p>
+
+<h3><a NAME="1.0alpha1ant">Ant</a></h3>
+
+<p> An Ajdoc task is now available. The Ajc ant task was improved to
+be completely back-compatible with the Javac task.</p>
+
+<h3><a NAME="1.0alpha1ajbrowser">AJBrowser</a></h3>
+
+<p> The "AspectJ Browser" is a new standalone source code browsing application.
+It will let you compile ".lst" files, view the structure for those files and
+navigate the corresponding source code.</p>
+
+<h3><a name="1.0alpha1ajde">AJDE</a></h3>
+
+<h4>AJDE for JBuilder</h4>
+
+<h5>Installation</h5>
+<ul>
+ <li>Use the installer to place the "ajdeForJBuilder.jar" and "aspectjrt.jar"
+ in to JBuilder's lib/ext directory.</li>
+</ul>
+
+<h5>Key Improvements</h5>
+
+<ul>
+ <li>The "AspectJ Structure View" replaces JBuilder's structure view instead of
+ being launched in a separate window.</li>
+ <li>AJDE can be toggled on/off with the "AJ" button--when it is turned off all
+ of the menus, resources, and event listeners that it uses will be removed.</li>
+ <li>Projects no longer require the manual adding of the "aspectjrt.jar"
+ libarary.</li>
+</ul>
+
+<h5>Known Bugs &amp; Limitations</h5>
+
+<ul>
+ <li>There is no compiler progress dialog--the way to tell if the compile is
+ finished is to watch the "status" area of the main window.</li>
+ <li>There are no keyboard compile/execute shortcuts.</li>
+ <li>The structure view is not persistent between IDE launches--you must
+ compile to view the structure for a program.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ <li>There is no ajdoc tool support.</li>
+ <li>Linux testing has been very limited.</li>
+</ul>
+
+
+<h4>AJDE for Forte</h4>
+
+
+<h5>Installation</h5>
+
+<ul>
+ <li>Use the installer to place the "ajdeForForte.jar" in Forte's
+ modules directory and "aspectjrt.jar"
+ in to Forte's lib/ext directory.</li>
+ <li>
+ In the "Tools" menu select "Global Options"</li>
+ <li>
+ Right-click the "Modules" item and select "New Module from
+ File..."</li>
+ <li>
+ Find the ajdeForForte.jar in the directory that you installed into (e.g.
+ c:\forte4j\modules) and
+ select it.</li>
+</ul>
+
+<h5>Key Improvements</h5>
+
+<ul>
+ <li>AJDE can be toggled on/off with the "AJ" button--when it is turned off all
+ of the menus, resources, and event listeners that it uses will be removed.</li>
+ <li>The AJDE functionality is now contained within it's own toolbar and menu.</li>
+</ul>
+
+<h5>Known Bugs &amp; Limitations</h5>
+
+<ul>
+ <li>"Mode" switching is not supported in this version--you must do all of your
+ AspectJ work in the "Editing" mode. If you switch modes the IDE has to
+ be restarted for the AspectJ window to show again.</li>
+ <li>There is no compiler progress dialog--the way to tell if the compile is
+ finished is to watch the "status" area of the main window.</li>
+ <li>There are no keyboard compile/execute shortcuts.</li>
+ <li>The structure view is not persistent between IDE launches--you must
+ compile to view the structure for a program.</li>
+ <li>The debugger has not seen much use and it's stability and performance is
+ limited.</li>
+ <li>There is no ajdoc tool support.</li>
+ <li>Linux testing has been very limited.</li>
+</ul>
+
+<h4>AJDE for Emacs</h4>
+
+<p> AspectJ-mode now includes a toggle in the AspectJ menu that
+disables its intrusive functions, enabling easy switching between Java
+and AspectJ projects. See the README and CHANGES files in the
+distribution for additional details. </p>
+
+<p> AJDEE is now compatible with JDEE 2.2.7.1, JDEE 2.2.8beta4, and speedbar
+0.14alpha. It a toggle in the AspectJ menu that disables its intrusive
+functions, enabling easy switching between Java and AspectJ projects. See
+the README and CHANGES files in the distribution for additional details.
+</p>
+
+
+<hr />
+
+<h2><a name="oldversions">Previous Versions</a></h2>
+
+<p> Changefiles for previous versions can be found in
+<code>doc/oldversions</code> in the documentation distribution.
+</p>
+
+
+</body>
+</html>
diff --git a/docs/dist/doc/index.html b/docs/dist/doc/index.html
new file mode 100644
index 000000000..b3977f439
--- /dev/null
+++ b/docs/dist/doc/index.html
@@ -0,0 +1,329 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html> <head>
+<LINK rel="STYLESHEET" href="../style.css">
+<!-- type="text/css": Error: no attribute "TYPE" for this element (in 3.2) -->
+<title>AspectJ Documentation and Resources</title>
+</head>
+<body>
+<a name="top"></a>
+<h1>AspectJ Documentation and Resources</h1>
+<p>
+ AspectJ <sup><small>tm</small></sup>
+ is a seamless aspect-oriented extension to
+ Java<sup><small>tm</small></sup>.
+ The compiler and development tools are available under
+ an open-source license, require Java 2 to run, and produce
+ code that runs in JDK 1.1 and later VM's.
+ For the latest materials, see
+ <a href="@aspectj.home.url@">@aspectj.home.url@</a>,
+ especially the <a href="@aspectj.home.url@/faq">FAQ</a>.
+<p>
+
+<table>
+ <tr><td><u>Section</u></td><td><u>Contents</u></td></tr>
+ <tr><td><a href="#documentation">docs</a></td><td>
+ <a href="faq.html">FAQ</a>,
+ <a href="quick.pdf">Quick Reference</a>,
+ <a href="progguide/index.html">programming</a> and
+ <a href="devguide/index.html">development</a> guides,
+ <a href="api/overview-summary.html">API</a> and
+ <!-- start strip -->
+ (<a href="../examples/">local</a>)
+ <!-- end strip -->
+ examples
+ <tr><td><a href="#distributions">distributions</a></td><td>
+ compiler, AJDE, docs, and Ant taskdefs
+ (<a href="@aspectj.home.url@/dl">binary</a>
+ - <a href="@aspectj.home.url@/sources">source</a>)
+ <tr><td><a href="#resources">resources</a></td><td>
+ <a href="http://aosd.net">aosd.net</a>;
+ <a href="@aspectj.home.url@">aspectj.org</a>
+ bug <a href="@aspectj.home.url@/bugs">db</a> and
+ <a href="mailto:jitterbug@aspectj.org">email</a>,
+ mail <a href="@aspectj.home.url@/lists">lists</a> for
+ <a href="mailto:users@aspectj.org">users</a> and
+ <a href="mailto:support@aspectj.org">support</a>
+ <tr><td><a href="#paths">paths</a> </td><td>for those new to AspectJ
+</table>
+<p>
+
+<a name="documentation"></a>
+<h3>AspectJ documentation</h3>
+<table border="1">
+<tr> <th>Documentation</th><th>Description</th>
+ </tr>
+
+<tr> <td><a href="quick.pdf"> AspectJ Quick Reference</a>
+ <!-- start strip -->
+ (<a href="@aspectj.home.url@/doc/dist/quick.pdf">web</a>)
+ <!-- end strip -->
+ </td>
+ <td>This is a two-page quick reference for the AspectJ language.
+ </td> </tr>
+
+
+<tr> <td><a href="progguide/index.html">Programming Guide</a>
+ (printable <a href="progguide.pdf">pdf</a> or <a href="progguide/printable.html">html</a>
+ <!-- start strip -->
+ - <a href="@aspectj.home.url@/doc/dist/progguide/index.html">web</a>
+ <!-- end strip -->
+ )
+ </td>
+ <td>This introduces AOP and the AspectJ language.
+ <a href="progguide/ch01.html">Getting Started</a>
+ describes basic semantics, and shows development- and production-time applications.
+ <a href="progguide/ch02.html">The AspectJ Language</a>
+ describes join points, pointcuts, advice, and introduction, all features new to AOP.
+ <a href="progguide/ch03.html">Examples</a> walks you through the
+ examples included with the documentation, and there are two short
+ chapters on useful <a href="progguide/ch04.html">Idioms</a> and a
+ few <a href="progguide/ch05.html">Pitfalls</a>
+ The appendices have reference information:
+ the <a href="progguide/apa.html">Quick Reference</a>
+ summarizes AspectJ syntax,
+ the <a href="progguide/apb.html">Language Semantics</a>
+ best describes AspectJ usage, and
+ <a href="progguide/apc.html">Implementation Limitations</a> notes that
+ the current version is limited to code the compiler controls.</td>
+ </tr>
+
+<tr> <td><a href="devguide/index.html">Development Environment Guide</a><br>
+
+ (printable <a href="devguide/printable.html">html</a>
+ <!-- start strip -->
+ - <a href="@aspectj.home.url@/doc/dist/devguide/index.html">web</a>
+ <!-- end strip -->
+ )
+ </td>
+ <td>Find here a guide to the command-line compiler <u><tt>ajc</tt></u>
+ and API doc tool <u><tt>ajdoc</tt></u>, as well as
+ the <u>AspectJ Development Environment (AJDE)</u> for managing crosscutting
+ structure in JBuilder, Forte, Emacs, and the stand-alone <tt>ajbrowser</tt>.
+ (For using <tt>ajc</tt> and <tt>ajdoc</tt> in
+ <a href="http://jakarta.apache.org/ant">Ant</a> builds,
+ see the <code>taskdefs</code> distribution.)
+ </td>
+ </tr>
+
+<tr> <td><a href="api/overview-summary.html">AspectJ API</a>
+ <!-- start strip -->
+ (<a href="@aspectj.home.url@/doc/dist/api/overview-summary.html">web</a>)
+ <!-- end strip -->
+ </td>
+ <td>API documentation for AspectJ runtime classes. <tt>JoinPoint</tt>
+ shows the state automatically available at each join point.
+ </td> </tr>
+
+<tr> <td><a href="faq.html"> FAQ</a>
+ <!-- start strip -->
+ (<a href="@aspectj.home.url@/doc/dist/faq.html">web</a>)
+ <!-- end strip -->
+ </td>
+ <td>Frequently-asked questions about the AspectJ language, tools, and project.
+ </td> </tr>
+
+<tr> <td><a href="porting.html"> Porting guide</a>
+ <!-- start strip -->
+ (<a href="@aspectj.home.url@/doc/dist/porting.html">web</a>)
+ <!-- end strip -->
+ </td>
+ <td>How users can convert code from pre-1.0 versions
+ of AspectJ to 1.0.
+ </td> </tr>
+
+<tr> <td><a href="changes.html"> Changes </a>
+ <!-- start strip -->
+ (<a href="@aspectj.home.url@/doc/dist/changes.html">web</a>)
+ <!-- end strip -->
+ </td>
+ <td>Changes between the latest releases.
+ </td> </tr>
+
+<tr> <td>Examples
+ <!-- start strip -->
+ (<a href="../examples/">local</a>)
+ <!-- end strip -->
+ </td>
+ <td>AspectJ code to demonstrate some language features and implement
+ JavaBean properties, the Observer pattern, a tracing library,
+ and a game application where aspects handle display updating.
+ </td> </tr>
+
+</table>
+
+<a name="distributions"></a>
+<h3>AspectJ distributions</h3>
+<table border="1">
+<tr> <th>Distributions</th><th>Description</th>
+<tr> <td><a href="@aspectj.home.url@/dl">AspectJ</a>
+ </td>
+ <td>The AspectJ distribution contains binaries for the
+ compiler, structure browser, and Ant taskdefs,
+ as well as the documentation and examples.
+ (Source code for AspectJ is available from the CVS
+ repositories for the AspectJ project.)
+ </td>
+ </tr>
+
+<tr> <td><a href="http://eclipse.org/ajdt">AspectJ for Eclipse</a>
+ </td>
+ <td>AspectJ Development Environment support for
+ Eclipse is available under the Common Public License 1.0
+ from the eclipse.org project site
+ <a href="http://eclipse.org/ajdt">
+ http://eclipse.org/ajdt</a>
+ </td>
+ </tr>
+
+<tr> <td><a href="http://aspectj4emacs.sourceforge.net">
+ AspectJ for Emacs</a>
+ </td>
+ <td>AspectJ Development Environment support for
+ Emacs is available under the GPL
+ from the sourceforge project site
+ <a href="http://aspectj4emacs.sourceforge.net/">
+ http://aspectj4emacs.sourceforge.net</a>
+ </td>
+ </tr>
+
+<tr> <td><a href="http://aspectj4jbuildr.sourceforge.net">
+ AspectJ for JBuilder</a>
+ </td>
+ <td>AspectJ Development Environment support for
+ JBuilder is available under the Mozilla Public License 1.1
+ from the sourceforge project site
+ <a href="http://aspectj4jbuildr.sourceforge.net/">
+ http://aspectj4jbuildr.sourceforge.net</a>
+ </td>
+ </tr>
+
+<tr> <td><a href="http://aspectj4netbean.sourceforge.net">
+ AspectJ for Netbeans</a>
+ </td>
+ <td>AspectJ Development Environment support for
+ Netbeans is available under the Mozilla Public License 1.1
+ from the sourceforge project site
+ <a href="http://aspectj4netbean.sourceforge.net/">
+ http://aspectj4netbean.sourceforge.net</a>
+ </td>
+ </tr>
+
+</table>
+
+<a name="resources"></a>
+<h3>Other AspectJ resources</h3>
+<table border="1">
+<tr> <th>Resources</th><th>Description</th>
+ </tr>
+<tr> <td>
+ user
+ <a href="mailto:users@aspectj.org">email</a>
+ <a href="@aspectj.home.url@/lists">list</a>
+ </td>
+ <td>Developers use the
+ <a href="mailto:users@aspectj.org">users@aspectj.org</a>
+ mail list to discuss tips and
+ best practices for developing with AspectJ.
+ </td> </tr>
+
+<tr> <td>
+ announce
+ <a href="mailto:announce@aspectj.org">email</a>
+ <a href="@aspectj.home.url@/lists">list</a>
+ </td>
+ <td>
+ <a href="mailto:announce@aspectj.org">announce@aspectj.org</a>
+ has notices about releases and AspectJ team events.
+ </td> </tr>
+
+<tr> <td>
+ <a href="mailto:support@aspectj.org">email</a> us
+ </td>
+ <td>
+ Email <a href="mailto:support@aspectj.org">support@aspectj.org</a>
+ to contact the AspectJ team directly.
+ (As a small team, we cannot reply as fast as
+ <a href="mailto:users@aspectj.org">users</a>
+ can for usage questions.)
+ </td> </tr>
+
+<tr> <td>Bug
+ <a href="@aspectj.home.url@/bugs">DB</a>
+ and <a href="mailto:jitterbug@aspectj.org">email</a>
+ </td>
+ <td>Please send AspectJ bugs! (as a small program
+ that reproduces the problem)
+ </td> </tr>
+
+<tr> <td> <a href="http://aosd.net">http://aosd.net</a> - the AOSD web site
+ </td>
+ <td>This site has discussion and announcements related to
+ aspect-oriented software development (AOSD) in general.
+ Use <a href="mailto:announce@aosd.net">announce@aosd.net</a>
+ to get and publish notices about AOSD
+ workshops, conferences, and technology releases.
+ Use <a href="mailto:announce@aosd.net">discuss@aosd.net</a>
+ for general AOSD discussions.
+ </td> </tr>
+</table>
+
+<p>
+<a name="paths"></a>
+<h3>Suggested paths for those new to AspectJ</h3>
+<p>
+ To learn the AspectJ language, read the
+ <a href="progguide/index.html">Programming Guide</a>,
+ keeping the <a href="progguide/apb.html">Semantics appendix</a>
+ nearby as the best reference for AspectJ usage.
+ Focus initially on the join point model and
+ pointcuts, concepts AOP adds to OOP.
+ To see how the code works, tour your
+ <!-- start strip -->
+ <a href="../examples/">local</a>
+ <!-- end strip -->
+ examples as described in the
+ <a href="progguide/ch03.html">Examples </a> section of the
+ <a href="progguide/index.html">Programming Guide</a>.
+ View and navigate the crosscutting structure using
+ the <code>ajbrowser</code> structure viewer, as described in
+ the <a href="devguide/rn02re04.html">ajbrowser</a> section of
+ the <a href="devguide/index.html">Development Environment Guide</a>.
+<p>
+ To start using AspectJ with your own code,
+ modify the example aspects to apply to your classes.
+ The <a href="devguide/index.html">Development Environment Guide</a>
+ shows how to build using the command-line tools.
+ As you learn,
+ use the compiler's <code>-Xlint</code> flag to catch some common
+ mistakes. (Understand that the
+ <a href="progguide/apc.html">current implementation</a>
+ is limited to code the compiler controls.)
+<p>
+ To plan how to adopt AspectJ into a project, read the
+ <a href="progguide/index.html">Programming Guide</a>
+ on development- and production-time aspects
+ and the <a href="faq.html">FAQ</a> entries for
+ <a href="faq.html#q:startUsingAJ">How should I start using AspectJ?</a>,
+ <a href="faq.html#adoption">Deciding to adopt AspectJ</a>,
+ the Development tools sections
+ (<a href="faq.html#q:integrateWithDevTools">one</a>,
+ <a href="faq.html#devtools">two</a>),
+ <a href="faq.html#q:opensource">AspectJ as open-source</a> and
+ <a href="faq.html#q:consulting">available support and consulting</a>.
+</p>
+<p>
+ Otherwise, see
+ the <a href="faq.html">FAQ</a>,
+ <a href="@aspectj.home.url@/lists">view</a> or
+ <a href="mailto:users@aspectj.org">email</a> the
+ AspectJ users list, and enjoy the language!
+</p>
+<p>
+The AspectJ Team
+</p>
+
+<hr>
+<small>
+<a href="#top">Top</a>
+</small>
+</body> </html>
diff --git a/docs/dist/doc/porting.html b/docs/dist/doc/porting.html
new file mode 100644
index 000000000..0a4d558a3
--- /dev/null
+++ b/docs/dist/doc/porting.html
@@ -0,0 +1,1785 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+
+<head>
+<LINK rel="STYLESHEET" href="../style.css" type="text/css">
+<title>AspectJ 1.0.6 Reference - Porting Notes</title>
+</head>
+
+<body>
+
+<DIV ALIGN=right CLASS=copyrightNotice>
+&copy; Copyright 1998-2002 Palo Alto Research Center Incorporated. All rights reserved.
+</DIV>
+
+<h1>Porting Notes</h1>
+
+<ul>
+ <li><a href="#pre-1.0.4">Pre-1.0.4 code</a></li>
+ <li><a href="#pre-1.0rc1">Pre-1.0rc1 code</a></li>
+ <li><a href="#pre-1.0beta1">Pre-1.0beta1 code</a></li>
+ <li><a href="#pre-1.0alpha1">Pre-1.0alpha1 code</a>
+ </li>
+ <li><a href="#pre08b3">Pre-0.8beta3 code</a></li>
+
+ <li><a href="#pre08b1">Pre-0.8beta1 code</a></li>
+
+ <li><a href="#pre07b11">Pre-0.7beta11 code</a></li>
+
+ <li><a href="#pre07b10">Pre-0.7beta10 code</a></li>
+</ul>
+
+<h2><a name="pre-1.0.4">Porting pre-1.0.4 code</a></h2>
+
+<p>In versions of AspectJ prior to 1.0.4, the compiler was not
+correctly implementing the AspectJ-1.0 language design for some uses
+of after returning advice.
+</p>
+
+<p> The main change that was made was of after returning advice for
+constructor execution join points. Previously, this advice was legal:
+</p>
+
+<PRE>
+after() returning (Foo f): execution(Foo.new(..)) { ... }
+</PRE>
+
+<p> However, it has always been a part of the 1.0 language design (and
+of Java's language design) that constructors themselves (as opposed to
+constructor calls) do not return the value of the new object. Rather,
+<code>this</code> is bound to the new object, and the constructor
+behaves like a void method. With that in mind, any code like the
+above should be conveted to the form. </p>
+
+<PRE>
+after(Foo f) returning: this(f) &amp;&amp; execution(Foo.new(..)) { ... }
+</PRE>
+
+<p> In compilers prior to 1.0.4, the following advice could pick out
+join points
+</p>
+
+<PRE>
+after() returning (String s): call(void foo()) { ... }
+</PRE>
+
+<p> This is no longer picked out. This pattern was most commonly used
+in highly polymorphic contexts, such as
+</p>
+
+<PRE>
+after() returning (String s): call(* foo()) { ... }
+</PRE>
+
+<p> If you want to capture all calls, binding null objects for those
+that would otherwise have no value, you must use the
+<code>Object</code> type.
+</p>
+
+<PRE>
+after() returning (Object o): call(* foo()) { ... }
+</PRE>
+
+<p> Uses of both of these forms are highleted with compiler warnings
+in the 1.0.4 compiler.
+</p>
+
+
+<hr />
+
+<h2><a name="pre-1.0rc1">Porting pre-1.0rc1 code</a></h2>
+
+<p> Aspects can no longer be declared to implement the
+<code>Serializable</code> or <code>Cloneable</code> interfaces. If
+you previously used serializable or cloneable aspects, you should
+refactor your code to keep the state you need to serialize or clone in
+objects associated with the aspects.
+</p>
+
+<hr />
+
+<h2><a name="pre-1.0beta1">Porting pre-1.0beta1 code</a></h2>
+
+<p> The <code>static</code> modifier is no longer allowed on pointcut
+declarations anywhere. Porting is simple; just remove the static
+declarations when you find them.
+</p>
+
+<p> Also, though the <code>returns</code> modifier on pointcuts has
+not been part of the language since 1.0alpha1, the compiler still
+accepted them until now. If you used this feature, now is the right
+time to remove the <code>returns</code> modifier when the compiler
+complains about it.
+</p>
+
+<hr />
+
+<h2><a name="pre-1.0alpha1">Porting pre-1.0alpha1 code </a></h2>
+
+
+<p> The release of AspectJ 1.0alpha1 involved sweeping cleanups of the
+language to bring it to 1.0 status. </p>
+
+ <ul>
+ <li><a href="#1.0a1-pointcuts">Pointcuts</a></li>
+ <li><a href="#1.0a1-type-patterns">Type patterns</a></li>
+ <li><a href="#1.0a1-advice">Advice</a></li>
+ <li><a href="#1.0a1-introduction-and-static">Introduction and
+ static crosscutting</a></li>
+ <li><a href="#1.0a1-aspects">Aspects</a></li>
+ </ul>
+
+<h3><a name="1.0a1-pointcuts">Pointcuts</a></h3>
+
+<h4><a name="1.0a1-plural-to-singular">Removing the "s" from pointcuts</a></h4>
+
+<p> One of the most pervasive changes in porting code written before
+1.0alpha1 is the change in some of the pointcut names from plural to
+singular, that is, they lose an "s". In one sense, making this change
+in your programs is easy: just go through and whever you see uses of
+the pointcuts
+</p>
+
+<blockquote>calls executions gets sets handlers initializations
+staticinitializations</blockquote>
+
+<p> Just take off the final "s", to make one of
+</p>
+
+<blockquote>call execution get set handler initialization
+staticinitialization</blockquote>
+
+<p> Often, there will be other changes you should make for each of
+these pointcuts, but as for the name, just take off the "s". </p>
+
+<p> One risk you will have when doing this is creating name conflicts.
+If, for example, you named a parameter of a pointcut "set", you should
+(for your own sanity -- the compiler doesn't require it) rename it in
+the rewritten pointcut. </p>
+
+<PRE>
+pointcut sort(Collection set): calls(void addAll(set));
+==&gt;
+pointcut sort(Collection mySet): call(void addAll(mySet));
+</PRE>
+
+<p> While converting to use singular nouns for the primitive
+pointcuts, you may also want to remove the "s" from your user-defined
+pointcuts. </p>
+
+<PRE>
+pointcut publicCalls(): calls(public * *(..));
+==&gt;
+pointcut publicCall(): call(public * *(..));
+</PRE>
+
+<p> Of course, your naming conventions are your own, but throughout
+these porting notes we will be making these changes in our example
+ports. </p>
+
+
+<h4><a name="1.0a1-remove-receptions">Removing the receptions pointcut</a></h4>
+
+<p> Perhaps the largest semantic change in the 1.0 language is the
+removal of receptions join points. They have been merged with call
+join points in AspectJ 1.0, so now a call join point doesn't represent
+the "caller-side" of a call, but the call itself, both caller and
+receiver. </p>
+
+<p> Changing code that used the <code>receptions</code> pointcut should be
+fairly straightforward, depending on whether the pointcut exposed state or
+not. </p>
+
+<h5>Not exposing state</h5>
+
+<p> Receptions pointcuts that did not expose state can simply be
+replaced by the new <code>call</code> and <code>target</code> pointcuts:</p>
+
+<PRE>
+receptions(void Foo.m())
+==&gt;
+target(Foo) && call(void m())
+</PRE>
+
+<h5>Exposing state</h5>
+
+<p> Some receptions pointcuts exposed the receiving object by
+replacing the receiving type with a pointcut formal. These PCDs
+should be rewritten to use the new <code>target</code> pointcut to expose
+the receiving object. </p>
+
+<PRE>
+pointcut fooCallees(Foo f): receptions(void f.m());
+==&gt;
+pointcut fooCallee(Foo f): target(f) &amp;&amp; call(void m());
+</PRE>
+
+<p> Like <a href="#1.0a1-fixing-state-access">other pointcuts</a>,
+receptions pointcuts that exposed one or more arguments should be
+rewritten to use the <code>args</code> pointcut: </p>
+
+<PRE>
+pointcut intPassers(int i, int j): receptions(void Foo.m(i, j));
+==&gt;
+pointcut intPasser(int i, int j):
+ args(i, j) &amp;&amp; target(Foo) &amp;&amp; call(void m(int, int));
+</PRE>
+
+<h5>Constructor receptions</h5>
+
+<p> There are two issues with constructor receptions in
+particular. </p>
+
+<p>Like <a href="#1.0a1-constructor-calls">constructor calls</a>,
+constructor receptions pointcuts had a dynamic character, in that
+<code>receptions(C.new())</code> would capture constructions of not
+only C classes, but also of classes that extended C. </p>
+
+<p> If you want this behaviour, then you need to use the new subtypes
+operator, +, on the type name in question. So,
+</p>
+
+<PRE>
+receptions(C.new())
+==&gt;
+call(C+.new())
+</PRE>
+
+<p>Also like <a href="#1.0a1-constructor-calls">constructor calls</a>,
+constructor receptions allowed access to the constructed object in the
+same way as any other object. Since the only advice possible on
+constructor receptions join points was <code>after returning</code>
+advice, the object was always guaranteed to be there. But since
+constructor call join points allow all kinds of advice it may be that
+the object isn't constructed yet (say, in before or around advice).
+This is a benefit, in that it allows caching constructed objects </p>
+
+<PRE>
+aspect Singleton {
+ private C theC = null;
+
+ C around(): call(C.new(..)) {
+ if (c == null) theC = proceed();
+ return theC;
+ }
+}
+</PRE>
+
+<p> but it does require some rewriting. The new object can be
+accessed as the return value in after returning advice. So, </p>
+
+<PRE>
+after(Point p) returning (): receptions(p.new(int, int)) { ... }
+==&gt;
+after() returning (Point p): call(Point+.new(int, int)) { ... }
+</PRE>
+
+<h4><a name="1.0a1-fixing-state-access">Fixing state access</a></h4>
+
+<p> In previous versions of AspectJ, state such as the currently
+executing object or a particular argument of a method call could be
+accessed from the signatures of many pointcuts, leading to
+difficult-to-read forms. In AspectJ 1.0, all state accesses now use
+only three pointcuts </p>
+
+<blockquote>args this target</blockquote>
+
+<p> which pick out argument values, the currently executing object,
+and the target object of a method call or field operation,
+respectively. </p>
+
+<h5>Using args</h5>
+
+<p> Any time you have a pointcut that has a signature where one of the
+arguments was a pointcut or advice formal, just replace that formal
+with its type and add an <code>args</code> pointcut.
+</p>
+
+<PRE>
+pointcut intPassers(int i, int j): calls(void Foo.m(i, j));
+==&gt;
+pointcut intPasser(int i, int j): args(i, j) &amp;&amp; call(void Foo.m(int, int));
+</PRE>
+
+<PRE>
+pointcut stringPassers(String s): receptions(void Foo.m(s, ..));
+==&gt;
+pointcut stringPasser(String s): args(s, ..) &amp;&amp; call(void Foo.m(String, ..));
+</PRE>
+
+<h5>Rewriting calls</h5>
+
+<p> If a calls pointcut exposed the the receiving object, such as </p>
+
+<PRE>
+pointcut fooCallees(Foo f): calls(void f.m());
+</PRE>
+
+<p> then the new version should use the <code>target</code> pointcut
+to get at that object
+</p>
+
+<PRE>
+pointcut fooCallee(Foo f): target(f) &amp;&amp; call(void Foo.m());
+</PRE>
+
+<p> AspectJ's calls pointcut previously allowed the new object to be
+exposed, even though it may not have been constructed yet. AspectJ
+1.0 no longer allows this; you can access the new instance only in
+after returning advice, when it is guaranteed that the object was
+successfully constructed. So instead of using the <code>target</code>
+pointcut to expose the value, you should use the normal <code>after
+returning</code> mechanism:
+</p>
+
+<PRE>
+after(Point p) returning (): calls(p.new(int, int)) { ... }
+==&gt;
+after() returning (Point p): call(Point+.new(int, int)) { ... }
+</PRE>
+
+
+<h5>Rewriting gets and sets</h5>
+
+<p> Exposing the target object of a <code>gets</code> or
+<code>sets</code> pointcut should be done the same way it was for
+<code>calls</code> pointcuts, with the new <code>target</code>
+pointcut. </p>
+
+<PRE>
+before(Frame f): gets(Color f.color) { ... }
+==&gt;
+before(Frame f): target(f) &amp;&amp; get(Color Frame.color) { ... }
+</PRE>
+
+<PRE>
+before(Frame f): sets(Color f.color) { ... }
+==&gt;
+before(Frame f): target(f) &amp;&amp; set(Color Frame.color) { ... }
+</PRE>
+
+<p> In addition, the clumsy syntax for getting the old value of the
+field has been eliminated. For before advice, the port is simple;
+just access the field yourself in the body. Depending on the rest of
+your system, you may need to restrict the advice from the aspect body
+to eliminiate the circularity. </p>
+
+<PRE>
+aspect A {
+ before(Frame f, Color c): gets(Color f.color)[c] { ... }
+}
+==&gt;
+aspect A {
+ before(Frame f):
+ target(f) &amp;&amp; get(Color Frame.color) &amp;&amp; !within(A) {
+ Color c = f.color;
+ ...
+ }
+}
+</PRE>
+
+<p> The same can be done for <code>around</code> advice. However, the
+only way to port after advice that needs the old value is to convert
+it to around advice.
+</p>
+
+<PRE>
+aspect A {
+ after(Frame f, Color c) returning (): gets(Color f.color)[c] { ... }
+}
+==&gt;
+aspect A {
+ void around(Frame f):
+ target(f) &amp;&amp; get(Color Frame.color) &amp;&amp; !within(A) {
+ Color c = f.color;
+ proceed(f);
+ ...
+ }
+}
+</PRE>
+
+<p> When porting <code>sets</code> pointcuts, the new value of a field
+is still available, but not the way it was previously. Instead of
+using the square bracket syntax, we use an <code>args</code> pointcut.
+All set join points are assumed to have exactly one argument, which
+holds the new value. So, </p>
+
+<PRE>
+after(Color newColor): sets(Color Frame.color)[][newColor] { ... }
+==&gt;
+after(Color newColor): args(newColor) &amp;&amp; set(Color Frame.color) { ... }
+</PRE>
+
+<p> Also, if the field was declared private, in order to get at its
+old value the aspect must be declared <code>privileged</code>.
+</p>
+
+<h5>Rewriting handlers</h5>
+
+<p> The value of the exception at an exception handler join point is
+now accessed through the <code>args</code> pointcut; all exception
+handler join points are treated as having exactly one argument, the
+exception value. So,
+</p>
+
+<PRE>
+before(NotFoundException e): handlers(e) { ... }
+==&gt;
+before(NotFoundException e): args(e) &amp;&amp; handler(NotFoundException) { ... }
+</PRE>
+
+<h5>Rewriting within</h5>
+
+<p> The <code>within</code> pointcut was not typically used to export
+context. Though it was accidentally possible to do so in versions of
+AspectJ before 1.0, it often didn't do what users expected it to.
+This loophole has now been closed, and within can only take type
+patterns, not pointcut or advice formals. A use of the
+<code>this</code> pointcut will capture what previous implementations
+did: </p>
+
+<PRE>
+pointcut usesFoo(Foo f): within(f);
+==&gt;
+pointcut usesFoo(Foo f): this(f) &amp;&amp; within(Foo);
+</PRE>
+
+<h4><a name="1.0a1-no-subs-in-sigs">Understanding signatures</a></h4>
+
+<p> Now that we have <code>this</code>, <code>target</code>, and
+<code>args</code> pointcuts, all of our signatures are composed of
+just types, names, and wildcards; there are no more parameters.
+</p>
+
+<p> Also, now that we have the <code>+</code> wildcard to pick out
+<a href="#1.0a1-subtypes-to-plus">subtypes</a>, we can make signature
+matching much more uniform.</p>
+
+<p> Previously, some signatures matched based on subtypes, some based
+on instanceof, and some exactly. Now, we have made all signatures
+match exactly.
+</p>
+
+<p> What does this mean for your program? Well, it means that you
+may have to add <code>+</code> to some of your signatures, depending
+on what you meant them to match.
+</p>
+
+<p> For example, the pointcut
+</p>
+
+<pre>
+calls(void m(Object))
+</pre>
+
+<p> previously picked out all method calls to a method named m that
+took one argument, which was a subtype of Object. Now, however, it
+will only pick out method calls to methods that are defined to take
+exactly the type Object, which may be a lot fewer join points. If you
+want the old behaviour, simply convert to </p>
+
+<pre>
+call(void m(Object+))
+</pre>
+
+<h4><a name="1.0a1-fixing-instanceof">Removing the instanceof pointcut</a></h4>
+
+<p> The intanceof pointcut has been split into two different
+pointcuts, <code>this</code> and <code>target</code>. </p>
+
+<p> Typically, the instanceof pointcut would only exist in a compound
+pointcut, composed (with <CODE>&amp;&amp;</CODE>) with another
+pointcut. If the other pointcut was a <code>receptions</code>
+pointcut, then <code>instanceof</code> should be converted to
+<code>target</code> (and <code>receptions</code> converted to
+<code>call</code>). So, </p>
+
+<PRE>
+pointcut stateChanges(Subject s):
+ instanceof(s) &amp;&amp; receptions(void Button.click());
+==&gt;
+pointcut stateChange(Subject s):
+ target(s) &amp;&amp; call(void Button.click());
+</PRE>
+
+<p> In all other cases, <code>instanceof</code> referred to the
+currently executing object, and so should be converted into
+<code>this</code></p>
+
+<PRE>
+before(Point p): instanceof(p) &amp;&amp; executions(* makePolar(..)) { ... }
+==&gt;
+before(Point p): this(p) &amp;&amp; execution(* makePolar(..)) { ... }
+</PRE>
+
+<PRE>
+pointcut setup(Client c): instanceof(c) &amp;&amp; calls(Remote Naming.lookup(String));
+==&gt;
+pointcut setup(Client c): this(c) &amp;&amp; calls(Remote Naming.lookup(String));
+</PRE>
+
+<h4><a name="1.0a1-initializations">Rewriting the initializations pointcut</a></h4>
+
+<p> Object initialization join points are now more complicated, and
+more true to Java's execution model. Now they bracket all of the
+initialization that a class can do, after the return of its super
+constructor call (before which no initialization can happen). Previous
+versions of AspectJ had object initialization join points that only
+included initialization that was made in dynamic initializers and
+fields. </p>
+
+<p> The old behaviour can be recovered with a simple rewrite.
+</p>
+
+<PRE>
+initializations(A)
+==&gt;
+initialization(A.new(..)) &amp;&amp; !execution(A.new(..))
+</PRE>
+
+<h4><a name="1.0a1-constructor-calls">Understanding constructor calls</a></h4>
+
+<p> Previously, constructor call join points were matched by subtypes,
+so <code>calls(Foo.new())</code> would match both calls to create new
+<code>Foo</code> objects, and new <code>SubFoo</code> objects. The
+new <code>call</code> pointcut designator matches types exactly, so if
+you want the old behaviour, you should write
+<code>call(Foo+.new())</code>. </p>
+
+<p> Similarly, constructor execution join points were matched by
+subtypes. So the old <code>executions(Foo.new())</code> is now
+represented by <code>execution(Foo+.new())</code>.
+</p>
+
+<p> In both of these cases, think before using the + operator; it may
+be that you didn't intend subtype matching in the first place. </p>
+
+<h4><a name="1.0a1-hasaspect">Removing the hasaspect pointcut</a></h4>
+
+<p> The <code>hasaspect</code> pointcut is no longer defined, but you
+can get the same behaviour using the new <code>if</code> pointcut.
+</p>
+
+<p> If the aspect whose presense you are checking for was defined
+<code>of eachcflow</code>, <code>of eachcflowbelow</code>, or, more
+unlikely, <code>of eachJVM()</code>, then the conversion is simple:
+</p>
+
+<PRE>
+hasaspect(A)
+==&gt;
+if(A.hasAspect())
+</PRE>
+
+<p> If the aspect was defined <code>of eachobject</code>, then you
+will have to expose the current object in your pointcut or advice
+parameters: </p>
+
+<PRE>
+pointcut cut(): hasaspect(A) ... ;
+==&gt;
+pointcut cut(Object o): this(o) &amp;&amp; if(A.hasAspect(o)) ... ;
+or
+pointcut cut(Object o): target(o) &amp;&amp; if(A.hasAspect(o)) ... ;
+</PRE>
+
+<p> If you were using the <code>hasaspect</code> pointcut to expose
+the state of the aspect, then you can get the same state by using
+<code>A.aspectOf()</code> in the body of the advice. For example, if
+the aspect A were defined <code>of eachcflow</code>, then
+</p>
+
+<PRE>
+before(A myA): hasaspect(myA) {
+ myA.checkStatus();
+}
+==&gt;
+before(): if(A.hasAspect()) {
+ A myA = A.aspectOf();
+ myA.checkStatus();
+}
+</PRE>
+
+<h4><a name="1.0a1-withinall">Removing the withinall pointcut</a></h4>
+
+<p> The withinall poinctut is no longer defined. You can use a
+combination of within and the <a href="#1.0a1-subtypes-to-plus">new
+subtypes operator</a>, +, instead. You'll save two characters and be
+using a simpler and more orthogonal language. </p>
+
+<PRE>
+withinall(Foo)
+==&gt;
+within(Foo+)
+</PRE>
+
+<h4><a name="1.0a1-user-defined-returns">Removing returns modifier from pointcuts</a></h4>
+
+<p>The returns keyword is no longer necessary for user-defined
+pointcuts. Simply remove it when you find it. </p>
+
+<PRE>
+pointcut publicIntCalls() returns int: calls(public int *(..));
+==&gt;
+pointcut publicIntCall(): call(public int *(..));
+</PRE>
+
+<h4><a name="1.0a1-static-pointcuts">Making some pointcuts static</a></h4>
+
+<p> In Java, only static members may be accessed by their declaring
+type name, like the static method <code>Math.max()</code> can be
+accessed. </p>
+
+<p> Pointcuts now have that property too. Pointcuts may be declared
+to be static, in which case they can be accessed like
+<code>MyAspect.move()</code>, or they can be left non-static, in which
+case they can be overridden by a subaspect. </p>
+
+<p> In addition, while pointcuts can still be defined in classes, only
+<code>static</code> pointcuts can be defined in classes. </p>
+
+<p> Porting should be straightforward; just make all your pointcuts in
+classes <code>static</code>, and make any pointcut with a qualified
+reference static.
+</p>
+
+<h3><a name="1.0a1-type-patterns">Type patterns</a></h3>
+
+<h4><a name="1.0a1-new-wildcards">Understanding * and .. in type patterns</a></h4>
+
+<p> Previous versions of AspectJ treated * and .. too cleverly in type
+patterns, placing restrictions based on what is a package and what is
+a type, and basing their meanings on the definition of a package
+hierarchy. </p>
+
+<p> In AspectJ 1.0, both of these wildcards are defined simply, and
+textually:
+</p>
+
+<ul>
+ <li> The * wildcard alone matches all types. </li>
+
+ <li> The * wildcard in a pattern matches zero or more characters,
+ but will not match "." </li>
+
+ <li> The .. wildcard matches any sequence of characters that begins
+ and ends with "." </li>
+</ul>
+
+<p> That's it.
+</p>
+
+<p> This change won't affect most programs, but it will make
+understanding programs easier. There is one ugly idiom, however, that
+this change disposes of. If your program includes the type pattern
+<code>*..*</code>, which used to match all types, you can replace it with the
+much simpler *. </p>
+
+<PRE>
+pointcut unaryVoidMethods(): call(void *(*..*));
+==&gt;
+pointcut unaryVoidMethod(): call(void *(*));
+</PRE>
+
+<h4><a name="1.0a1-subtypes-to-plus">Fixing subtypes in introduction</a></h4>
+
+<p> The new + operator is used to normalize the many places you want
+to use subtypes of some types.
+</p>
+
+<p> In introduction forms, you will need to replace
+<code>subtypes(<var>TypePattern</var>)</code> type patterns with the
+new subtype operator, +. In the case where you wrote
+<code>subtypes(Foo)</code>, i.e., the subtypes of a single type,
+simply replace this with <code>Foo+</code>. Otherwise, use the
++ operator as appropriate in <var>TypePattern</var>. </p>
+
+<PRE>
+public void (subtypes(Target0 || Target1)).accept(Visitor v) {
+ v.visit(this);
+}
+==&gt;
+public void (Target0+ || Target1+).accept(Visitor v) {
+ v.visit(this);
+}
+</PRE>
+
+<h3><a name="1.0a1-advice">Advice</a></h3>
+
+<h4><a name="1.0a1-around-returns">Moving the return type of around</a></h4>
+
+<p> The returns keyword is no longer used for around advice. Instead,
+the return type is declared as it is for methods. So, </p>
+
+<PRE>
+around(Point p) returns void: setters(p) { ... }
+==&gt;
+void around(Point p): setter(p) { ... }
+</PRE>
+
+<h4><a name="1.0a1-around-throws">Adding a throws clause to around</a></h4>
+
+<p> Around advice must now declare the checked exceptions it throws
+with a <code>throws</code> clause, much like a method.
+</p>
+
+<PRE>
+char around(char c) throws java.io.CharConversionException: converter(c) {
+ char result;
+ try { result = proceed(); }
+ catch (Exception e) {
+ throw new java.io.CharConversionException();
+ }
+ if (result == 0) throw new java.io.CharConversionException();
+ return result;
+}
+</PRE>
+
+<h4><a name="1.0a1-advice-precedence">Understanding advice precedence</a></h4>
+
+<p> In previous versions of AspectJ, advice precedence within an
+aspect was simple: if a piece of advice appeared before another piece,
+it was more precedent. This made perfect sense for
+<code>before</code> and <code>around</code> advice, but was the cause
+of confusion (even among the AspectJ designers, more than once) for
+<code>after</code> advice, as it seemed backward. </p>
+
+<p> In addition, advice was ordered by kind, in that around advice
+always surrounded before and after advice.
+</p>
+
+<p> AspectJ 1.0 has changed this; precedence for <code>after</code>
+advice is inverted, and advice is no longer ordered by kind.
+</p>
+
+<p>This won't matter to you unless you write pieces of advice in the
+same aspect that apply to the same join point. </p>
+
+<p>If you do, here's what to think about: If you're looking at two
+pieces of advice and want to know which has precedence, if either is
+<code>after</code> advice, then the second one has precedence.
+Otherwise, the first does. </p>
+
+<p> This allows interesting advice interaction. In the following
+advice, for example, the <code>after throwing</code> advice will catch
+the exception thrown by the <code>before</code> advice </p>
+
+<PRE>
+aspect A {
+ before(): call(void main(..)) {
+ throw new RuntimeException();
+ }
+ after() throwing(RuntimeException e): call(void main(..)) {
+ System.err.println("caught you!");
+ }
+}
+</PRE>
+
+<p> But reversing the order will give the <code>before</code> advice
+more precedence, making its exception uncatchable by the <code>after
+throwing</code> advice
+</p>
+
+<PRE>
+aspect A {
+ after() throwing(RuntimeException e): call(void main(..)) {
+ System.err.println("missed you!");
+ }
+ before(): call(void main(..)) {
+ throw new RuntimeException();
+ }
+}
+</PRE>
+
+<p> Advice in <em>different</em> aspects is ordered by the normal aspect
+precedence rules of subtyping and the <code>dominates</code> modifier.
+</p>
+
+<h4><a name="1.0a1-after-returning">Fixing after returning</a></h4>
+
+<p> If you use after returning advice and do not need to expose the
+return value, you no longer need to write an empty set of parentheses
+to indicate that fact. So, </p>
+
+<pre>
+after(<var>Formals</var>) returning (): <var>Pointcut</var> { ... }
+==&gt;
+after(<var>Formals</var>) returning: <var>Pointcut</var> { ... }
+</pre>
+
+<p> The same syntax is now available for after throwing advice, in
+case you do not care what <code>Throwable</code> is thrown.
+</p>
+
+<pre>
+after(<var>Formals</var>) throwing: <var>Pointcut</var> { ... }
+</pre>
+
+<h4><a name="1.0a1-this-static-join-point">Renaming thisStaticJoinPoint</a></h4>
+
+<p> <code>thisStaticJoinPoint</code> has been renamed
+<code>thisJoinPointStaticPart</code>, to reflect that it is now
+exactly the static part of <code>thisJoinPoint</code>: It will return
+the same object as <code>thisJoinPoint.getStaticPart()</code>. </p>
+
+<h4><a name="1.0a1-this-join-point">Converting access to thisJoinPoint</a></h4>
+
+<p> The <code>JoinPoint</code> object hierarchy has been folded into a
+single class, <code>org.aspectj.lang.JoinPoint</code>. A common
+pattern in logging, for example, was </p>
+
+<pre>
+before() executions(* myMethod()) {
+ ExecutionJoinPoint jp = (ExecutionJoinPoint)thisJoinPoint;
+ CodeSignature jp = (CodeSignature)jp.getSignature();
+ System.err.println(jp.getParameters());
+ System.err.println(jp.getParameterNames());
+}
+</pre>
+
+<p> While there is still a rich hierarchy for signatures, there is
+only one <code>JoinPoint</code> type, so this can be rewritten as:
+</p>
+
+<pre>
+before() executions(* myMethod()) {
+ JoinPoint jp = thisJoinPoint;
+ CodeSignature jp = (CodeSignature)jp.getSignature();
+ System.err.println(jp.getArgs());
+ System.err.println(jp.getParameterNames());
+}
+</pre>
+
+<p> Some of the method names of <code>JoinPoint</code> have been
+reorganized, as well. </p>
+
+<h3><a name="1.0a1-introduction-and-static">Introduction and static crosscutting</a></h3>
+
+<h4><a name="1.0a1-plus-implements-extends">Removing +implements and +extends</a></h4>
+
+<p> The keywords <code>+implements</code> and <code>+extends</code> no
+longer exist. Instead, AspectJ uses the <code>declare</code>
+form for exactly the same functionality. </p>
+
+<PRE>
+Point +implements Serializable;
+=&gt;
+declare parents: Point implements Serializable;
+</PRE>
+
+<PRE>
+MyButton +extends ButtonAdaptor;
+=&gt;
+declare parents: MyButton extends ButtonAdaptor;
+</PRE>
+
+<h4><a name="1.0a1-now-use-soft">Using declare soft</a></h4>
+
+<p> Around advice advice no longer effects the static exception
+checking of Java. This means that the following code previously
+compiled: </p>
+
+<PRE>
+class C {
+ void noExceptionDeclared() {
+ exceptionDeclared();
+ }
+ void exceptionDeclared() throws IOException {}
+}
+aspect A {
+ around(): call(void C.exceptionDeclared()) {
+ try { proceed(); }
+ catch (IOException e) {}
+ }
+}
+</PRE>
+
+<p> even though the class C is not compilable on its own (because
+noExceptionDeclared actually throws an Exception).
+</p>
+
+<p> AspectJ now firmly places everything that affects the type system
+of Java, including the declared-exception checking system, into the
+space of introduction and declare. So, in order to state that the
+call to exceptionDeclared() will not, actually, throw an exception, we
+now "soften" that exception, that is, take it out of the space of
+declared exceptions. </p>
+
+<pre>
+declare soft: <var>ExceptionType</var>: <var>Pointcut</var>;
+</pre>
+
+<p> The pointcuts allowed here are limited; you cannot use pointcuts
+that would require runtime information. But picking out method calls
+is just fine. So in order to make the above example work, one new
+declaration is needed:
+</p>
+
+<PRE>
+declare soft: IOException:
+ call(void C.exceptionDeclared()) &amp;&amp;
+ withincode(void noExceptionDeclared());
+</PRE>
+
+<h3><a name="1.0a1-aspects">Aspects</a></h3>
+
+<p> The syntax of "of each" modifiers has changed. For <code>of
+eachcflow</code> and <code>of eachcflowbelow</code>, you can simply
+replace "of each" with "per". So, </p>
+
+<PRE>
+aspect A of eachcflow(...) { ... }
+==&gt;
+aspect A percflow(...) { ... }
+</PRE>
+
+<p> If you have any aspects defined <code>of eachJVM()</code>, then
+you should either remove that declaration entirely (because this is
+the default behaviour), or replace the <code>of eachJVM()</code>
+declaration with an <code>issingleton</code> declaration.
+</p>
+
+<PRE>
+aspect of eachJVM() { ... }
+==&gt;
+aspect A { ... }
+or
+aspect A issingleton { ... }
+</PRE>
+
+<p> The <code>of eachobject(<var>Pointcut</var>)</code> modifier has
+been split into two different forms, <code>of
+perthis(<var>Pointcut</var>)</code> and <code>of
+pertarget(<var>Pointcut</var>)</code>. Which one you replace with
+depends on the <var>Pointcut</var> you use.
+</p>
+
+<p> If you use a pointcut that picked out reception join points, then
+use <code>pertarget</code>, and rewrite the pointcut to pick out call
+join points. So
+</p>
+
+<PRE>
+aspect Shadow
+ of eachobject(receptions(void Point.setX(int)) ||
+ receptions(void Point.setY(int))) {
+ ...
+}
+==&gt;
+aspect Shadow pertarget(call(void Point.setX(int)) ||
+ call(void Point.setY(int))) {
+ ...
+}
+</PRE>
+
+<p> Otherwise, in most cases, use <code>perthis</code>. When you
+convert, remember the meaning of each of these modifiers.
+<code>perthis(<var>Pointcut</var>)</code> indicates that an instance
+of the aspect should be associated with every object that is
+<code>this</code> at each of the join points picked out by
+<var>Pointcut</var>, while <code>pertarget(<var>Pointcut</var>)</code>
+associates with every object that is the target object at such join
+points. </p>
+
+<!-- ==================================== -->
+<!-- ==================================== -->
+<!-- ==================================== -->
+
+<hr />
+
+<h2><a name="pre08b3">Porting pre-0.8beta3 code</a></h2>
+
+<ul>
+ <li><a href="#cflowTerminology">Changing cflow terminology</a></li>
+ <li><a href="#abstractPointcuts">Overriding abstract pointcuts</a></li>
+ <li><a href="#recursiveAdvice">Limiting recursive advice</a></li>
+</ul>
+
+
+<p>The following changes are only required when porting code written
+prior to the 0.8beta3 release of AspectJ.</p>
+
+<h3><a name="cflowTerminology">Changing cflow terminology</a></h3>
+
+<p> Changing pre-0.8beta3 code that uses AspectJ's control-flow-based
+features only requires rewriting occurrences of
+<code>eachcflowroot</code>, <code>cflow</code>, and
+<code>cflowtop</code>. No editing of other aspect code is
+necessary.</p>
+
+<h4>eachcflowroot</h4>
+
+<p> The aspect modifier "<code>of
+eachcflowroot(<var>Pointcut</var>)</code>" should now be written more
+as "<code>percflow(<var>Pointcut</var>)</code>". </p>
+
+<h4>cflow</h4>
+
+<p> In previous versions of AspectJ, the pointcut
+<code>cflow(<var>Pointcut</var>)</code> picked out all join points in
+the cflow below the join points of <var>Pointcut</var>. That is, it
+did not include the join points of <var>Pointcut</var>, only the join
+points in their control flow.
+</p>
+
+<p> As of version 0.8beta3,
+<code>cflowbelow(<var>Pointcut</var>)</code> has that behavior.
+<code>cflow(<var>Pointcut</var>)</code> includes the join points of
+<var>Pointcut</var>. </p>
+
+<p> In many cases, you may not care whether the points of
+<var>Pointcut</var> are included or not, and so can safely leave
+<code>cflow(<var>Pointcut</var>)</code> pointcut designators alone.
+However, if you use the idiom
+</p>
+
+<pre class="codeindent">
+<var>Pointcut</var> && ! cflow(<var>Pointcut</var>)
+</pre>
+
+<p> to capture the non-recursive entries to a particular pointcut, you
+will definitely want to rewrite that as
+</p>
+
+<pre class="codeindent">
+<var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>)
+</pre>
+
+<h4>cflowtop</h4>
+
+<p> The primitive pointcut designator
+<code>cflowtop(<var>Pointcut</var>)</code> has been removed from the
+language, as it is expressible with <code>cflow</code> or
+<code>cflowbelow</code>. All uses of
+<code>cflowtop(<var>Pointcut</var>)</code> can be rewritten as:
+</p>
+
+<pre class="codeindent">
+cflowbelow(<var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>))
+</pre>
+
+<p> Though in most cases the following is sufficient
+</p>
+
+<pre class="codeindent">
+cflow(<var>Pointcut</var> && ! cflowbelow(<var>Pointcut</var>))
+</pre>
+
+<h3><a name="abstractPointcuts">Overriding abstract pointcuts</a></h3>
+
+<p> In previous versions of AspectJ, a concrete aspect would
+implicitly override all of its abstract pointcuts with an empty
+pointcut. AspectJ 0.8beta3 enforces the restriction that a concrete
+aspect may not have any abstract pointcuts. Thus the following
+extension:</p>
+
+<pre class="codeindent">
+abstract aspect A {
+ abstract pointcut pc();
+}
+
+aspect B {}
+</pre>
+
+<p> will no longer compile.
+</p>
+
+<p> Adding the new empty pointcut designator
+</p>
+
+<pre class="codeindent">
+pointcut <var>Id</var>();
+</pre>
+
+<p> in the declaration of the concrete aspect fixes this problem.
+</p>
+
+<pre class="codeindent">
+abstract aspect A {
+ abstract pointcut pc();
+}
+
+aspect B {
+ pointcut pc();
+}
+</pre>
+
+<h3><a name="recursiveAdvice">Limiting recursive advice</a></h3>
+
+<p> Previously, the compiler silently refrained from applying a piece
+of advice to join points within its own advice body. So, for example,
+in </p>
+
+<pre class="codeindent">
+class C {
+ static int i;
+}
+
+aspect A {
+ before(): gets(int C.i) {
+ System.err.println("C.i was " + C.i)
+ }
+}
+</pre>
+
+<p> The advice would trace all references of the static field
+<code>C.i</code> except those in the body of the before. </p>
+
+<p> The compiler has now removed this special case, and so running the
+above example will now cause a <code>StackOverflowException</code> to
+be thrown. </p>
+
+<p> Most cases of this error can be fixed by correctly specifying the
+desired pointcut: In the above example, the intention is clearly not
+to trace <em>all</em> references of <code>C.i</code>, just those
+outside the aspect.
+</p>
+
+<pre class="codeindent">
+class C {
+ static int i;
+}
+
+aspect A {
+ before(): get(int C.i) && ! within(A) {
+ System.err.println("C.i was " + C.i)
+ }
+}
+</pre>
+
+<p> In a very few cases, you may want the advice to be applicable to
+other code in the aspect, but not in the particular piece of advice.
+In such cases, you can pull the body of the advice into a method and
+restrict away from that method (and away from calls to that method):
+</p>
+
+<pre class="codeindent">
+class C {
+ static int i;
+}
+
+aspect A {
+ public static int getCi() {
+ return C.i; // will be traced
+ }
+
+ before(): get(int C.i) &&
+ ! withincode(void A.traceCi())
+ ! call(void A.traceCi()) {
+ traceCi();
+ }
+ private void traceCi() {
+ System.err.println("C.i was " + C.i) // will not be traced
+ }
+}
+</pre>
+
+
+<!-- ============================== -->
+
+<hr />
+<h2><a name="pre08b1">Porting pre-0.8beta1 code</a></h2>
+
+<ul>
+ <li><a href="#introSyntax">Rewriting introductions</a></li>
+ <li><a href="#staticAdvice">Removing static advice</a></li>
+ <li><a href="#aspect-aspect">Fixing aspect-aspect inheritance</a></li>
+ <li><a href="#usingPrivateIntroduction">Using private introduction</a></li>
+</ul>
+
+<p>The following changes are only required when porting code written
+prior to the 0.8beta1 release of AspectJ.</p>
+
+<h3><a name="introSyntax">Rewriting introductions</a></h3>
+
+<h4>Syntax</h4>
+
+<p> The syntax of introduction has changed. Porting most programs
+should require some simple editing. Anywhere you have an introduction
+block</p>
+
+<pre class="codeindent">
+introduction <var>GTN</var> {
+ ...
+}
+</pre>
+
+<p> simply move the <var>GTN</var> down into the introduction
+declarations and remove the block.</p>
+
+<p>For method introduction, place the <var>GTN</var> in front of the
+method name, For field introduction, place the <var>GTN</var> in front
+of the field name, and for constructor introduction, place the
+<var>GTN</var> in front of the <code>new</code> identifier. </p>
+
+<pre class="codeindent">
+introduction Foo {
+ public void doStuff() { this.doStuffLater(); }
+ public int calorieCount = 3;
+ public new(int x) { super(); calorieCount = x; }
+}
+
+==&gt;
+
+public void Foo.doStuff() { this.doStuffLater(); }
+public int Foo.calorieCount= 3;
+public Foo.new(int x) { super(); calorieCount = x; }
+</pre>
+
+<p> For implements and extends introduction, move the <var>GTN</var>
+in front of the new identifiers <code>implements</code> or
+<code>extends</code>, and place that in a <code>declare parents</code>
+form.
+</p>
+
+<pre class="codeindent">
+introduction Foo {
+ implements Comparable;
+ extends Goo;
+}
+
+==&gt;
+
+declare parents: Foo implements Comparable;
+declare parents: Foo extends Goo;
+</pre>
+
+<p> In all cases, if the <var>GTN</var> is just a type name, it can be
+moved down on its own. However, if the <var>GTN</var> uses any of
+<CODE>&amp;&amp;</CODE>, <code>||</code>, and <code>!</code>, it must
+be parenthesized. </p>
+
+<pre class="codeindent">
+introduction subtypes(Foo) &amp;&amp; !Goo {
+ int x;
+}
+
+==&gt;
+
+int (Foo+ &amp;&amp; !Goo).x;
+</pre>
+
+
+<h4>Access</h4>
+
+<p>If you had an introduction that was referring to private or
+protected members of the target class, this will no longer work. You
+will either need to modify your code to avoid this accessibility
+issue, or you will need to use the <code>privileged</code> modifier on
+the aspect that contains the introduction.</p>
+
+<pre class="codeindent">
+class Counter {
+ private int count = 2;
+}
+
+aspect ExposeCountersPrivates {
+ introduction Counter {
+ public int getCount() { return count; }
+ }
+}
+
+==&gt;
+// in 0.8, only privileged aspects can expose a class's privates
+privileged aspect ExposeCountersPrivates {
+ public int Counter.getCount() { return count; }
+}
+</pre>
+
+
+<p> If you have introduced private or package-protected members, you
+will probably have to re-write some code. Most previous uses of
+introducing privates can be improved by using private introduction
+instead.</p>
+
+<pre class="codeindent">
+class C {
+}
+
+aspect AddCounter {
+ introduction C {
+ private int count;
+ public int getCount() { return count; }
+ }
+}
+
+==&gt;
+aspect AddCounter {
+ private int Counter.count;
+ public int Counter.getCount() { return count; }
+}
+</pre>
+
+<p> There is one case that we know of where the inability to perform
+the introduction of private members makes 0.7 code difficult to
+port to 0.8. If you were using the introduction of a <code>private
+void writeObject(..)</code> or a <code>private void
+readObject(..)</code> method to interact with Java's serialization
+API, you will need to come up with an alternative design. Using some
+combination of <code>Externalizable</code>,
+<code>writeReplace(..)</code> and/or <code>readResolve(..)</code>
+methods should allow you to port your code. If you find this isn't
+the case, we'd like to hear about it.
+
+
+<p> If you were introducing either a protected member or a
+package-private member onto a class in order to override a protected
+member that was inherited from a superclass, you will have to make
+this introduction public. <p>
+
+
+<h3><a name="staticAdvice">Removing static advice</a></h3>
+
+<p> Static advice has been removed from the language. Now, every
+piece of advice is non-static, meaning that it will run in the context
+of an aspect instance.
+</p>
+
+<p> If you have an aspect that only contains static advice, has no
+"of" clause or is declared "of eachJVM()", and is not extended by
+another aspect, simply remove the keyword "static" from all pieces of
+advice, and make sure the aspect is not defined with the "abstract"
+modifier. </p>
+
+<pre class="codeindent">
+aspect Tracing {
+ static before(): executions(* *(..)) {
+ System.out.println("Got Here! " + thisJoinPoint);
+ }
+}
+
+==&gt;
+
+aspect Tracing {
+ before(): execution(* *(..)) {
+ System.out.println("Got Here! " + thisJoinPoint);
+ }
+}
+</pre>
+
+<p> Otherwise, if you have an aspect contains both static and
+non-static advice, is extended, or is "of eachObject(...)" or "of
+eachcflowroot(...)", you should group your static advice together and
+put it in a new aspect, possibly even an inner aspect. </p>
+
+<pre class="codeindent">
+aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) {
+ static before(): executions(* *(..)) {
+ System.out.println("Got Here! " + thisJoinPoint);
+ }
+ static after(): executions(* *(..)) {
+ System.out.println("Returned! " + thisJoinPoint);
+ }
+
+ // some other dynamic advice, fields, etc
+}
+
+==&gt;
+
+aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) {
+ static aspect AlwaysTracing {
+ before(): execution(* *(..)) {
+ System.out.println("Got Here! " + thisJoinPoint);
+ }
+ after(): execution(* *(..)) {
+ System.out.println("Returned! " + thisJoinPoint);
+ }
+ }
+
+ // some other dynamic advice, fields, etc
+}
+</pre>
+
+<h3><a name="aspect-aspect">Fixing aspect-aspect inheritance</a></h3>
+
+<p> Aspects can now only extend abstract aspects. This restriction
+may cause some redesign of aspect hierarchies. You will probably find
+that for the majority of your code the most serious change this
+requires is to add an explicit <code>abstract</code> modifier to a
+super-aspect that was already implicitly abstract.</p>
+
+<pre class="codeindent">
+aspect BaseTracing {
+ abstract pointcut traced();
+ before(): traced() {
+ System.out.println("Got Here! " + thisJoinPoint);
+ }
+}
+
+==&gt;
+
+// make this abstract aspect explicitly abstract
+abstract aspect BaseTracing {
+ ...
+}
+</pre>
+
+
+<p> This change has also affected the <code>getAspect</code> static
+method. Now, <code>getAspect</code> is only defined on non-abstract
+aspects. Previously, you could call <code>getAspect</code> on an
+abstract superaspect and (sometimes) get an instance of a subaspect
+back. </p>
+
+<p>This pattern was used in the Spacewar example in the AspectJ
+distribution. We had the class hierarchy </p>
+
+<pre>
+ SpaceObject (abstract)
+ |- Ship
+ |- Bullet
+ |- EnergyPellet
+</pre>
+
+<p> And the aspect hierarchy
+</p>
+
+<pre>
+ SpaceObjectDA (abstract)
+ |- ShipDA of eachobject(instanceof(Ship))
+ |- BulletDA of eachobject(instanceof(Ship))
+ |- EnergyPacketDA of eachobject(instanceof(Ship))
+</pre>
+
+<p> And we would call <code>SpaceObjectDA.getAspect(SpaceObject)</code> to access
+the aspect associated with a ship, bullet, or energy pellet. This
+pattern depended on the <code>SpaceObjectDA</code> aspect hierarchy
+exactly mirroring the <code>SpaceObject</code> hierarchy, and being
+maintained that way. </p>
+
+<p> A better way to implement this kind of design aspect is to use
+private introduction, a new feature of AspectJ.
+</p>
+
+<h3><a name="usingPrivateIntroduction">Using private introduction</a></h3>
+
+<p> A common pattern for AspectJ programs that need to associate some
+state with every object of a particular type has been to use aspects
+that are defined <code>of eachobject(instanceof(...))</code>. A prime
+example of this was the <code>BoundPoint</code> aspect of the bean
+example: which needed to associate each point with a
+<code>PropertyChangeSupport</code> object. </p>
+
+<pre class="codeindent">
+aspect BoundPoint of eachobject(instanceof(Point)) {
+
+ java.beans.PropertyChangeSupport support = null;
+
+ after() returning(Point p): receptions(p.new(..)){
+ support = new PropertyChangeSupport(myPoint);
+ }
+
+ around(Point p) returns void: receptions(void p.set*(*)) {
+ // code that uses support
+ }
+}
+</pre>
+
+<p> In the new version of AspectJ, a better way of accomplishing many
+of these state association is to use privately introduced fields.
+Instead of creating an aspect instance for every <code>Point</code>
+object, store the <code>PropertyChagneSupport</code> object in the
+<code>Point</code> objects themselves.
+</p>
+
+<pre class="codeindent">
+aspect BoundPoint {
+ private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
+
+ void around(Point p): setters(p) {
+ // code that uses p.support
+ }
+}
+</pre>
+
+<p> Just as in the past, the PropertyChangeSupport object is not
+accessable to anyone but the aspect, but now less mechanism is needed.
+</p>
+
+<p> There are times when changing aspects that are defined <code>of
+eachobject(instanceof(...))</code> may not be reasonable. If the
+aspect instance is stored or passed to other methods, then having a
+real <code>of eachobject(instanceof(...))</code>, now written
+<code>perthis(this(...))</code>, association may capture the
+crosscutting concern best. </p>
+
+<!-- ============================== -->
+
+<hr />
+<h2><a name="pre07b11">Porting pre-0.7beta11 code</a></h2>
+
+<ul>
+ <li><a href="#twoArgumentCalls">Removing two-argument calls</a></li>
+ <li><a href="#adviceInClasses">Removing advice from Class declarations</a></li>
+</ul>
+
+<p>The following changes are only required when porting code written
+prior to the 0.7beta11 release of AspectJ.</p>
+
+<h3><a name="twoArgumentCalls">Removing two-argument calls</a></h3>
+
+<p> In AspectJ 0.7beta11, the two-argument <code>calls</code>
+primitive pointcut designator was deprecated. Removing these
+designators will require different cases depending on what the
+original pointcut did. </p>
+
+<h4>Calls to static methods</h4>
+
+<p> For pointcuts denoting calls to particular static methods, such as
+</p>
+
+<blockquote><pre>
+calls(String, static String valueOf(int)) // deprecated
+</pre></blockquote>
+
+<p> the transformation is easy. Simply make the desired signature
+explicit. Instead of catching all calls to any static method that
+happens to have the signature <code>String valueOf(int)</code>, catch
+calls to that exact method defined in the String class. </p>
+
+<blockquote><pre>
+call(static String String.valueOf(int))
+</pre></blockquote>
+
+<p> Pointcuts denoting calls to classes of static methods can also be
+rewritten with these rules. For example, </p>
+
+<blockquote><pre>
+calls(my.package.*, static * get*(..)) // deprecated
+</pre></blockquote>
+
+<p> should now be written </p>
+
+<blockquote><pre>
+call(static * my.package.*.get*(..))
+</pre></blockquote>
+
+<h4>Calls to non-static methods</h4>
+
+<p> Many pointcuts denoting calls to non-static methods can be
+fixed the same way that those pointcuts denoting calls to static
+methods are fixed. So,
+</p>
+
+<blockquote><pre>
+calls(Thread, int getPriority()) // deprecated
+</pre></blockquote>
+
+<p> which denotes all calls to nullary int methods named <code>getPriority</code>
+when the called object is an instance of the <code>Thread</code> type,
+can almost always be rewritten </p>
+
+<blockquote><pre>
+call(int Thread.getPriority())
+</pre></blockquote>
+
+<p> which denotes all calls to the nullary int <code>Thread.getPriority()</code>
+method.
+</p>
+
+<p> Expanding the signature picks out slightly different join points
+than the original two-argument form. This won't matter for most
+programs, but in some cases the differences may be noticable. In
+particular, the expanded-signature form only picks out those calls
+where the called object is statically typed to <code>Thread</code>
+when its <code>int getPriority()</code> method is called. If you want
+to capture calls to the <code>int Thread.getPriority()</code> method,
+regardless of how the called object is statically typed, you shoud use
+the different translation: </p>
+
+<blockquote><PRE>
+call(int getPriority()) &amp;&amp; target(Thread)
+</PRE></blockquote>
+
+<p> This will capture all call join points of methods with signature
+<code>int Thread.getPriority()</code>. </p>
+
+<p> It will also denote any join points if the Thread type does not
+define (possibly abstractly) some <code>int getPriority()</code>
+method, though. </p>
+
+
+<h3><a name="adviceInClasses">Removing advice from Class declarations</a></h3>
+
+<p> The simplest way to remove an advice declaration from a class is
+to simply define the advice declaration in an inner aspect. So,
+instead of </p>
+
+<blockquote><pre>
+class C {
+ static before(): executions(C.new()) { ... } // deprecated
+}
+</pre></blockquote>
+
+<p> write </p>
+
+<blockquote><pre>
+class C {
+ static aspect ConstructionProtocol {
+ static before(): executions(C.new()) { ... }
+ }
+}
+</pre></blockquote>
+
+<p> If your advice doesn't refer to any inner classes or interfaces of
+C, you can move the inner aspect out of the class entirely. </p>
+
+<blockquote><pre>
+class C { ... }
+
+aspect ConstructionProtocol {
+ static before(): execution(C.new()) { ... }
+}
+</pre></blockquote>
+
+<p> Your code will be clearer if you consider the purpose of each
+piece of advice when you make this change. It may be that some of the
+advice naturally belongs to another aspect, perhaps already existing.
+Or it may be that some pieces of advice in a class are associated to
+one concern and some to another; in which case more than aspect would
+be appropriate. </p>
+
+<!-- ============================== -->
+<hr />
+<h2><a name="pre07b10">Porting pre-0.7beta10 code</a></h2>
+
+<ul>
+ <li><a href="#joinPoints">Changing access to thisJoinPoint</a></li>
+</ul>
+
+<p>The following changes are only required when porting code written
+prior to the 0.7beta10 release of AspectJ.</p>
+
+
+<h3><a name="joinPoints">Changing access to thisJoinPoint</a></h3>
+
+<p> In AspectJ 0.7beta10, access to the reflective object
+<code>thisJoinPoint</code> substantially changed. The two parts of
+this change were the elimination of the <code>runNext()</code> static
+method, and the use of an interface hierarchy represent the join point
+object. </p>
+
+<h4><a name="proceed"><code>thisJoinPoint.runNext()</code> to
+<code>proceed()</code></a></h4>
+
+<p> The elimination of the <code>runNext()</code> static method
+requires almost no porting work. An automatic replacement of the
+string
+</p>
+
+<blockquote><code>thisJoinPoint.runNext</code></blockquote>
+
+<p> with the string
+</p>
+
+<blockquote><code>proceed</code></blockquote>
+
+<p> will do the job. However, if any around advice used the
+identifier "<code>proceed</code>" as a formal parameter or local
+variable, it must be renamed, and if any aspect used it as a field,
+then references to the field in around advice should be made explicit
+(prefixing the reference with the aspect name or "<code>this</code>",
+depending on whether the field is static or not). </p>
+
+<h4><a name="thisJoinPoint">Using <code>thisJoinPoint</code></a></h4>
+
+<p> While access to reflective information through
+<code>thisJoinPoint</code> is more powerful and regular through its
+interface hierarchy, the previous uses must be rewritten. Changing
+your code will likely require manual editing, but in doing so your
+code should get simpler and cleaner. </p>
+
+<!-- -->
+
+<p> Many existing uses of the fields on join points can be re-written
+to use one of:
+</p>
+
+<ul>
+ <li><code>thisJoinPoint.toString()</code></li>
+ <li><code>thisJoinPoint.toShortString()</code></li>
+ <li><code>thisJoinPoint.toLongString()</code></li>
+ <li><code>thisJoinPoint.getSignature().toString()</code></li>
+ <li><code>thisJoinPoint.getSignature().toShortString()</code></li>
+ <li><code>thisJoinPoint.getSignature().toLongString()</code></li>
+</ul>
+
+<p>For example:
+</p>
+
+<blockquote><pre>
+System.out.println(thisJoinPoint.className + "." +
+ thisJoinPoint.methodName)
+</pre></blockquote>
+
+<p> can be replaced with
+</p>
+
+<blockquote><code>System.out.println(thisJoinPoint)</code></blockquote>
+
+<p> or
+</p>
+
+<blockquote><code>System.out.println(thisJoinPoint.getSignature().toShortString())</code></blockquote>
+
+<p> with comparable behavior.
+</p>
+
+<!-- -->
+
+<p> Accesses to the parameters field of join points should be changed
+as follows. A field access like:
+</p>
+
+
+<blockquote><code>thisJoinPoint.parameters</code></blockquote>
+
+<p> must be changed to:
+</p>
+<ul>
+ <li><code>thisJoinPoint.getArgs()</code></li>
+</ul>
+
+<!-- -->
+
+<p> Accesses to the methodName and className fields of join points
+that are not suitable for replacement with a toString method,
+should be changed as follows. Field accesses like:
+</p>
+
+<ul>
+ <li><code>thisJoinPoint.className</code></li>
+ <li><code>thisJoinPoint.methodName</code></li>
+</ul>
+
+<p> must be changed to:
+</p>
+
+<ul>
+ <li><code>thisJoinPoint.getSignature().getDeclaringType().getName()</code></li>
+ <li><code>thisJoinPoint.getSignature().getName()</code></li>
+</ul>
+
+<!-- -->
+
+<p> Accessses to the parameterNames and parameterTypes fields of
+join points, that are not suitable for conversion to one of the
+toString() methods should be changed as follows. Field access
+like:
+</p>
+
+<ul>
+ <li><code>thisJoinPoint.parameterNames</code></li>
+ <li><code>thisJoinPoint.parameterTypes</code></li>
+</ul>
+
+<p> must be changed to:
+</p>
+
+<ul>
+ <li><code>((CodeSignature)thisJoinPoint.getSignature()).getParameterNames()</code></li>
+ <li><code>((CodeSignature)thisJoinPoint.getSignature()).getParameterTypes()</code></li>
+</ul>
+
+</body>
+</html>
diff --git a/docs/dist/doc/quick.doc b/docs/dist/doc/quick.doc
new file mode 100644
index 000000000..89857a0b8
--- /dev/null
+++ b/docs/dist/doc/quick.doc
Binary files differ
diff --git a/docs/dist/examples/bean/BoundPoint.java b/docs/dist/examples/bean/BoundPoint.java
new file mode 100644
index 000000000..c247ca9cd
--- /dev/null
+++ b/docs/dist/examples/bean/BoundPoint.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1998-2002 Xerox Corporation. All rights reserved.
+ *
+ * Use and copying of this software and preparation of derivative works based
+ * upon this software are permitted. Any distribution of this software or
+ * derivative works must comply with all applicable United States export
+ * control laws.
+ *
+ * This software is made available AS IS, and Xerox Corporation makes no
+ * warranty about the software, its performance or its conformity to any
+ * specification.
+ */
+package bean;
+
+import java.beans.*;
+import java.io.Serializable;
+
+/*
+ * Add bound properties and serialization to point objects
+ */
+
+aspect BoundPoint {
+ /*
+ * privately introduce a field into Point to hold the property
+ * change support object. `this' is a reference to a Point object.
+ */
+ private PropertyChangeSupport Point.support = new PropertyChangeSupport(this);
+
+ /*
+ * Introduce the property change registration methods into Point.
+ * also introduce implementation of the Serializable interface.
+ */
+ 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 describing the set<property> methods on Point.
+ * (uses a wildcard in the method name)
+ */
+ pointcut setter(Point p): call(void Point.set*(*)) && target(p);
+
+ /**
+ * Advice to get the property change event fired when the
+ * setters are called. It's around advice because you need
+ * the old value of the property.
+ */
+ 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());
+ }
+ }
+
+ /*
+ * Utility to fire the property change event.
+ */
+ void firePropertyChange(Point p,
+ String property,
+ double oldval,
+ double newval) {
+ p.support.firePropertyChange(property,
+ new Double(oldval),
+ new Double(newval));
+ }
+}
diff --git a/docs/dist/examples/bean/Demo.java b/docs/dist/examples/bean/Demo.java
new file mode 100644
index 000000000..767409878
--- /dev/null
+++ b/docs/dist/examples/bean/Demo.java
@@ -0,0 +1,83 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+*/
+package bean;
+
+import java.beans.*;
+import java.io.*;
+
+public class Demo implements PropertyChangeListener {
+
+ static final String fileName = "test.tmp";
+
+ /**
+ * when Demo is playing the listener role,
+ * this method reports that a propery has changed
+ */
+ public void propertyChange(PropertyChangeEvent e){
+ System.out.println("Property " + e.getPropertyName() + " changed from " +
+ e.getOldValue() + " to " + e.getNewValue() );
+ }
+
+ /**
+ * main: test the program
+ */
+ 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);
+ }
+
+ /**
+ * Save a serializable object to a file
+ */
+ static void save(Serializable p, String fn){
+ try {
+ System.out.println("Writing to file: " + p);
+ FileOutputStream fo = new FileOutputStream(fn);
+ ObjectOutputStream so = new ObjectOutputStream(fo);
+ so.writeObject(p);
+ so.flush();
+ } catch (Exception e) {
+ System.out.println(e);
+ System.exit(1);
+ }
+ }
+
+ /**
+ * Restore a serializable object from the file
+ */
+ static Object restore(String fn){
+ try {
+ Object result;
+ System.out.println("Reading from file: " + fn);
+ FileInputStream fi = new FileInputStream(fn);
+ ObjectInputStream si = new ObjectInputStream(fi);
+ return si.readObject();
+ } catch (Exception e) {
+ System.out.println(e);
+ System.exit(1);
+ }
+ return null;
+ }
+
+
+}
diff --git a/docs/dist/examples/bean/Point.java b/docs/dist/examples/bean/Point.java
new file mode 100644
index 000000000..d5040c2bf
--- /dev/null
+++ b/docs/dist/examples/bean/Point.java
@@ -0,0 +1,76 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+*/
+
+package bean;
+
+class Point {
+
+ protected int x = 0;
+ protected int y = 0;
+
+ /**
+ * Return the X coordinate
+ */
+ public int getX(){
+ return x;
+ }
+
+ /**
+ * Return the y coordinate
+ */
+ public int getY(){
+ return y;
+ }
+
+ /**
+ * Set the x and y coordinates
+ */
+ public void setRectangular(int newX, int newY){
+ setX(newX);
+ setY(newY);
+ }
+
+ /**
+ * Set the X coordinate
+ */
+ public void setX(int newX) {
+ x = newX;
+ }
+
+ /**
+ * set the y coordinate
+ */
+ public void setY(int newY) {
+ y = newY;
+ }
+
+
+ /**
+ * Move the point by the specified x and y offset
+ */
+ public void offset(int deltaX, int deltaY){
+ setRectangular(x + deltaX, y + deltaY);
+ }
+
+
+ /**
+ * MAke a string of this
+ */
+ public String toString(){
+ return "(" + getX() + ", " + getY() + ")" ;
+ }
+
+
+
+}
diff --git a/docs/dist/examples/build.xml b/docs/dist/examples/build.xml
new file mode 100644
index 000000000..08d7cdc05
--- /dev/null
+++ b/docs/dist/examples/build.xml
@@ -0,0 +1,282 @@
+
+<!-- ========================================================================= -->
+<!-- Copyright (c) 1999-2001 Xerox Corporation, -->
+<!-- 2002 Palo Alto Research Center, Incorporated (PARC). -->
+<!-- All rights reserved. -->
+<!-- This program and the accompanying materials are made available -->
+<!-- under the terms of the Common Public License v1.0 -->
+<!-- which accompanies this distribution and is available at -->
+<!-- http://www.eclipse.org/legal/cpl-v10.html -->
+<!-- -->
+<!-- Contributors: -->
+<!-- Xerox/PARC initial implementation -->
+<!-- ========================================================================= -->
+
+<project name="aspectj-examples" default="spacewar" basedir=".">
+
+ <target name="info" >
+ <echo>
+ This script builds the AspectJ examples.
+
+ Relevant targets:
+ spacewar build and run spacewar with debugging (default)
+ all build and run each example
+ {example} build and run any {example}
+ (use -projecthelp to list {example} names)
+
+ Setup:
+ - Run from the examples directory.
+ - Put aspectj-ant.jar in ../lib with aspectjtools.jar and aspectjrt.jar
+
+ Variants:
+ - To avoid running (i.e., compile only), define variable "norun"
+ - To define a variable, use the Ant -D option - e.g., on Windows:
+
+ ant -f build.xml -DJAVA_HOME=c:\jdk1.3.1 -Dnorun=skip
+
+ </echo>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- setup and cleanup targets -->
+ <!-- ============================================================= -->
+
+ <target name="clean" depends="init"
+ description="clean and create classes dir">
+ <delete quiet="on" dir="${classes.dir}"/>
+ <delete quiet="on">
+ <fileset dir="${example.dir}" includes="**/*.ajesym"/>
+ </delete>
+ <mkdir dir="${classes.dir}"/>
+ </target>
+
+ <target name="init" depends="init.variables,init.taskdefs"/>
+
+ <target name="init.variables"
+ description="init variables">
+
+ <!-- required directories - run from examples or predefine -->
+ <property name="example.dir"
+ location="${basedir}"/>
+ <property name="aspectj.lib.dir"
+ location="${basedir}/../lib"/>
+
+ <!-- required libraries - install or predefine -->
+ <property name="aspectj-ant.jar"
+ location="${aspectj.lib.dir}/aspectj-ant.jar"/>
+ <property name="aspectjrt.jar"
+ location="${aspectj.lib.dir}/aspectjrt.jar"/>
+ <property name="aspectjtools.jar"
+ location="${aspectj.lib.dir}/aspectjtools.jar"/>
+
+ <!-- created directories (fyi workingdir unused) -->
+ <property name="classes.dir"
+ location="${example.dir}/classes"/>
+ <property name="working.dir"
+ location="${example.dir}/ajworkingdir"/>
+
+ <!-- checking required libraries -->
+ <available file="${aspectjtools.jar}"
+ property="aspectjtools.jar.available"/>
+ <available file="${aspectjrt.jar}"
+ property="aspectjrt.jar.available"/>
+ <available file="${aspectj-ant.jar}"
+ property="aspectj-ant.jar.available"/>
+
+ <property name="example.packages"
+ value="bean, coordination, evolution, figures, figures.gui,
+ helloworld, icount, icount.lib, introduction,
+ observer, shadow, shadow.version1, shadow.version2,
+ spacewar, telecom, telecom.version1, timeserver, tjp,
+ tracing, tracing.lib tracing.version1, tracing.version2,
+ tracing.version3"/>
+ </target>
+
+ <target name="init.taskdefs" depends="init.variables,
+ aspectjtools.jar.available,
+ aspectjrt.jar.available,
+ aspectj-ant.jar.available">
+
+ <taskdef resource="org/aspectj/tools/ant/taskdefs/aspectjTaskdefs.properties">
+ <classpath>
+ <pathelement path="${aspectjtools.jar}"/>
+ <pathelement path="${aspectj-ant.jar}"/>
+ </classpath>
+ </taskdef>
+ </target>
+
+ <!-- targets to fail unless required libraries available -->
+
+ <target name="aspectjrt.jar.available" depends="init.variables"
+ unless="aspectjrt.jar.available" >
+ <fail message="expecting aspectjrt.jar at ${aspectjrt.jar}"/>
+ </target>
+
+ <target name="aspectjtools.jar.available" depends="init.variables"
+ unless="aspectjtools.jar.available" >
+ <fail message="expecting aspectjtools.jar at ${aspectjtools.jar}"/>
+ </target>
+
+ <target name="aspectj-ant.jar.available" depends="init.variables"
+ unless="aspectj-ant.jar.available" >
+ <fail message="expecting aspectj-ant.jar at ${aspectj-ant.jar}"/>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- these targets compile and run any example -->
+ <!-- ============================================================= -->
+ <target name="Ajx" depends="init"
+ description="compile {list} and run {class} of example">
+ <echo message="##### Ajx list=${list} class=${class}" />
+ <antcall target="clean" />
+
+ <ajc destdir="${classes.dir}" emacssym="on" argfile="${list}"
+ classpath="${aspectjrt.jar}"/>
+
+ <antcall target="Ajx-run" >
+ <param name="class" value="${class}"/>
+ </antcall>
+
+ </target>
+
+ <target name="Ajx-run"
+ description="run {class} unless {norun} is set"
+ unless="norun" >
+ <echo message="##### Ajx-run list=${list} class=${class}" />
+ <java classname="${class}" fork="yes">
+ <classpath>
+ <pathelement path="${classes.dir}"/>
+ <pathelement path="${aspectjrt.jar}"/>
+ </classpath>
+ </java>
+ </target>
+
+ <!-- ============================================================= -->
+ <!-- example targets -->
+ <!-- ============================================================= -->
+ <target name="all"
+ description="build and run all examples"
+ depends="bean,intro,intro-clone,intro-compare,intro-hash,
+ observer,spacewar,spacewar-demo,telecom,
+ telecom-timing,tracing-none,tracing-1,
+ tracing-2,tracing-3,tjp"/>
+
+ <target name="nonGui"
+ description="build and run non-GUI examples"
+ depends="bean,intro,intro-clone,intro-compare,intro-hash,
+ telecom,telecom-timing,tracing-none,tracing-1,
+ tracing-2,tracing-3,tjp"/>
+
+ <target name="bean">
+ <antcall target="Ajx">
+ <param name="list" value="bean/files.lst"/>
+ <param name="class" value="bean.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="intro">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.Point"/>
+ </antcall>
+ </target>
+
+ <target name="intro-clone">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.CloneablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="intro-compare">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.ComparablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="intro-hash">
+ <antcall target="Ajx">
+ <param name="list" value="introduction/files.lst"/>
+ <param name="class" value="introduction.HashablePoint"/>
+ </antcall>
+ </target>
+
+ <target name="observer">
+ <antcall target="Ajx">
+ <param name="list" value="observer/files.lst"/>
+ <param name="class" value="observer.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="spacewar">
+ <antcall target="Ajx">
+ <param name="list" value="spacewar/debug.lst"/>
+ <param name="class" value="spacewar.Game"/>
+ </antcall>
+ </target>
+
+ <target name="spacewar-demo">
+ <antcall target="Ajx">
+ <param name="list" value="spacewar/demo.lst"/>
+ <param name="class" value="spaceware.Game"/>
+ </antcall>
+ </target>
+
+ <target name="telecom">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/basic.lst"/>
+ <param name="class" value="telecom.BasicSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="telecom-billing">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/billing.lst"/>
+ <param name="class" value="telecom.BillingSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="telecom-timing">
+ <antcall target="Ajx">
+ <param name="list" value="telecom/timing.lst"/>
+ <param name="class" value="telecom.TimingSimulation"/>
+ </antcall>
+ </target>
+
+ <target name="tjp">
+ <antcall target="Ajx">
+ <param name="list" value="tjp/files.lst"/>
+ <param name="class" value="tjp.Demo"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-none">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/notrace.lst"/>
+ <param name="class" value="tracing.ExampleMain"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-1">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev1.lst"/>
+ <param name="class" value="tracing.ExampleMain"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-2">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev2.lst"/>
+ <param name="class" value="tracing.ExampleMain"/>
+ </antcall>
+ </target>
+
+ <target name="tracing-3">
+ <antcall target="Ajx">
+ <param name="list" value="tracing/tracev3.lst"/>
+ <param name="class" value="tracing.ExampleMain"/>
+ </antcall>
+ </target>
+
+</project>
diff --git a/docs/dist/examples/coordination/Condition.java b/docs/dist/examples/coordination/Condition.java
new file mode 100644
index 000000000..18bbafee2
--- /dev/null
+++ b/docs/dist/examples/coordination/Condition.java
@@ -0,0 +1,37 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+/**
+ * Interface for pre-conditions that are passed to guardedEntry methods of
+ * Coordinator.
+ * Conditions should be passed as anonymous classes that simply implement
+ * the checkit method.
+ *
+ */
+public interface Condition {
+
+ /**
+ * This method is called automatically by Coordinator.guardedEntry(...)
+ * and it's called everytime the coordination state changes.
+ */
+
+ public boolean checkit();
+}
diff --git a/docs/dist/examples/coordination/CoordinationAction.java b/docs/dist/examples/coordination/CoordinationAction.java
new file mode 100644
index 000000000..7825b95b7
--- /dev/null
+++ b/docs/dist/examples/coordination/CoordinationAction.java
@@ -0,0 +1,37 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+/**
+ * Interface for coordination actions that are passed to guardedEntry methods of
+ * Coordinator.
+ * Coordination actions should be passed as anonymous classes that simply
+ * implement the doit method.
+ *
+ */
+public interface CoordinationAction {
+ /**
+ * This method is called by Coordinator.guardedEntry(...) and
+ * Coordinator.guardedExit(...). Use it for changing coordination state
+ * upon entering and exiting methods.
+ */
+
+ public void doit();
+}
diff --git a/docs/dist/examples/coordination/Coordinator.java b/docs/dist/examples/coordination/Coordinator.java
new file mode 100644
index 000000000..ea0522d6b
--- /dev/null
+++ b/docs/dist/examples/coordination/Coordinator.java
@@ -0,0 +1,449 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.util.*; //!!!
+
+/**
+ * The Coordinator class provides the basic functionality for synchronizing
+ * and coordinating different threads upon entering and exiting methods.
+ * It can be used in two different ways:
+ * 1) by instantiating regular coordinator objects that are used by aspects; or
+ * 2) by extending it (sub-classing) with coordinator aspects.
+ * <P>
+ * Method invocations are the smallest units for defining critical sections
+ * and pre-conditions. The use of coordinators, either regular objects or aspect
+ * instances, should always end up by invoking guardedEntry(...) in a
+ * before weave and guardedExit(...) in an after weave for all methods that
+ * need coordination. guardedEntry and guardedExit are the methods that
+ * actually manage the synchronization and coordination constraints given
+ * by their parameters and by pre-existent exclusion markers.
+ * <P>
+ * The synchronization of threads for the execution of critical section
+ * methods in an object is done by marking those methods as self- and/or
+ * mutually-exclusive (addSelfex, addMutex).
+ * Just by itself, addSelfex("M") does not enforce the self-exclusion
+ * of method M - enforcement is done by invoking guardedEntry before
+ * M is executed. Similarly, addMutex(new String[] {"M1", "M2"}) does
+ * not enforce the mutual exclusion between methods M1 and M2.
+ * <P>
+ * A guardedEntry on a method that has been marked as self-exclusive
+ * ensures that the method is executed in the invoked object by only one thread
+ * at a time. A guardedEntry on a method that has been marked has mutually-
+ * exclusive with other methods ensures that the execution of that method
+ * by a thread in the invoked object temporarily blocks the execution by
+ * other threads of the methods that are in the same mutex set.
+ * <P>
+ * The coordination of threads, i.e. their explicit suspension and
+ * resumption, is done through the use of pre-conditions and coordination
+ * actions that are passed as parameters to guardedEntry and guardedExit
+ * with the form of anonymous classes.
+ */
+public abstract aspect Coordinator {
+ private Hashtable methods = null;
+ private Vector exclusions = null;
+
+ abstract protected pointcut synchronizationPoint();
+
+ public Coordinator() {
+ methods = new Hashtable();
+ exclusions = new Vector(5);
+ }
+
+ before (): synchronizationPoint() {
+ this.guardedEntry(thisJoinPointStaticPart.getSignature().getName());
+ }
+
+ after (): synchronizationPoint() {
+ this.guardedExit(thisJoinPointStaticPart.getSignature().getName());
+ }
+
+ /**
+ * Takes a multi-part method name (eg "BoundedBuffer.put")
+ * and marks that method as self-exclusive.
+ * No checks are made with respect to the existence of the method
+ * whose name is given.
+ */
+ public synchronized void addSelfex(String methName) {
+ Selfex sex = new Selfex (methName);
+
+ // update db of all exclusions in this coordinator
+ exclusions.addElement(sex);
+
+ // update local info in method
+ Method aMeth = getOrSetMethod(methName);
+ aMeth.addExclusion(sex);
+ }
+
+ /**
+ * Takes a multi-part method name (e.g. "BoundedBuffer.put")
+ * and removes that method from the list of self-exclusive methods.
+ */
+ public synchronized void removeSelfex(String methName) {
+ for (int i = 0; i < exclusions.size(); i++) {
+ Exclusion sex = (Exclusion)exclusions.elementAt(i);
+ if ((sex instanceof Selfex) &&
+ (((Selfex)sex).methodName.equals(methName))) {
+
+ // update db of all exclusions in this coordinator
+ exclusions.removeElementAt(i);
+
+ // update local info in method
+ Method aMeth = getOrSetMethod(methName);
+ aMeth.removeExclusion(sex);
+ }
+ }
+ }
+
+ /**
+ * Takes an array of multi-part method names and marks those
+ * methods as mutually exclusive.
+ * No checks are made with respect to the existence of the methods
+ * whose names are given.
+ */
+ public synchronized void addMutex(String[] methNames) {
+ Mutex mux = new Mutex(methNames);
+
+ // update db of all exclusions in this coordinator
+ exclusions.addElement(mux);
+
+ // update local info in each method
+ for (int i = 0; i < methNames.length; i++) {
+ Method aMeth = getOrSetMethod(methNames[i]);
+ aMeth.addExclusion(mux);
+ }
+ }
+
+ /**
+ * Takes an array of multi-part method names that correspond
+ * to an existing mutex set and remove the mutual exclusion constraint.
+ * If the given mutex set does not exist, removeMutex does nothing.
+ */
+ public synchronized void removeMutex(String[] methNames) {
+ for (int i = 0; i < exclusions.size(); i++) {
+ Exclusion mux = (Exclusion)exclusions.elementAt(i);
+ if (mux instanceof Mutex) {
+ boolean same = true;
+ for (int j = 0; j < methNames.length; j++)
+ if (!methNames[j].equals(((Mutex)mux).methodNames[j]))
+ same = false;
+ if (same) {
+ // update db of all exclusions in this coordinator
+ exclusions.removeElementAt(i);
+
+ // update local info in each method involved
+ for (int j = 0; j < methNames.length; j++) {
+ Method aMeth = getOrSetMethod(methNames[j]);
+ aMeth.removeExclusion(mux);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This method is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, only the method name is given. The only constraints
+ * checked are the exclusion constraints.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ */
+ public synchronized void guardedEntry(String methName) {
+ guardedEntry(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, null);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but the given method is executed
+ * only when the given condition is true.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a condition.
+ * The constraints checked are the exclusion constraints and whether
+ * the given condition is true.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * If the condition is false, guardedEntry suspends the current thread.
+ * That thread remains suspended until the condition becomes true, in
+ * which case all constraints are rechecked before the method is executed.
+ * When all exclusion constraints are checked and the given condition is
+ * true, the given method is executed.
+ */
+ public synchronized void guardedEntry(String methName, Condition condition) {
+ guardedEntry(methName, condition, null);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but with an additional
+ * coordination action that is executed before the given method is
+ * executed.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a coordination action.
+ * The only constraints checked are the exclusion constraints.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * The given coordination action is executed just before the given method
+ * is executed.
+ */
+ public synchronized void guardedEntry(String methName,
+ CoordinationAction action) {
+ guardedEntry(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ },
+ action);
+ }
+
+ /**
+ * Just like guardedEntry(String methName), but the given method is executed
+ * only when the given condition is true; the additional
+ * coordination action that is executed before the given method is
+ * executed.
+ * guardedEntry is the guard for enforcing all synchronization and
+ * coordination constraints of a given method, and it should be called
+ * just before the method is executed.
+ * In this form, the method name is given along with a condition and
+ * a coordination action.
+ * The constraints checked are the exclusion constraints and whether the
+ * given condition is true.
+ * If the method was previousely marked as selfex (through addSelfex),
+ * guardedEntry ensures that the method is executed only when no other
+ * thread is executing it.
+ * If the method was previousely marked as being in one or more mutex
+ * sets, guardedEntry ensures that the method is executed only when no other
+ * thread is executing any of the methods with which the give method is
+ * mutexed.
+ * If the condition is false, guardedEntry suspends the current thread.
+ * That thread remains suspended until the condition becomes true, in
+ * which case all constraints are rechecked before the method is executed.
+ * When all exclusion constraints are checked and the given condition is
+ * true, the given method is executed.
+ * The given coordination action is executed just before the given method
+ * is executed.
+ */
+ public synchronized void guardedEntry(String methName,
+ Condition condition,
+ CoordinationAction action) {
+ Method aMeth = getOrSetMethod(methName);
+ boolean canGo = false;
+
+ // test pre-conditions for entering the method
+ while (!canGo) {
+ canGo = true;
+ for (int i = 0; i < aMeth.exes.size() && canGo; i++)
+ if (!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) {
+ canGo = false;
+ }
+ if (canGo && !condition.checkit()) {
+ canGo = false;
+ }
+ if (!canGo)
+ try {
+ wait();
+ } catch (InterruptedException e) { }
+ }
+
+ // OK.
+ enterMethod(aMeth, action);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, null, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ Condition condition,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, condition, null, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ CoordinationAction action,
+ long millis)
+ throws TimeoutException {
+ guardedEntryWithTimeout(methName, new Condition() {
+ public boolean checkit() {
+ return true;
+ }
+ }, action, millis);
+ }
+
+ /**
+ * This method is similar to guardedEntry, but it takes
+ * an additional parameter - the milliseconds after which any suspension
+ * will abort with a timeout.
+ */
+ public synchronized void guardedEntryWithTimeout(String methName,
+ Condition condition,
+ CoordinationAction action,
+ long millis)
+ throws TimeoutException {
+
+ Method aMeth = getOrSetMethod(methName);
+ boolean canGo = false;
+ long waitTime = millis;
+ long startTime = System.currentTimeMillis();
+
+ // test pre-conditions for entering the method
+ while (!canGo) {
+ canGo = true;
+ for (int i = 0; i < aMeth.exes.size() && canGo; i++)
+ if ((!((Exclusion)aMeth.exes.elementAt(i)).testExclusion(aMeth.name)) ||
+ (!condition.checkit())) {
+ canGo = false;
+ }
+ if (!canGo) {
+ try {
+ wait(waitTime);
+ } catch (InterruptedException e) {}
+
+ long now = System.currentTimeMillis();
+ long timeSoFar = now - startTime;
+ if (timeSoFar >= millis) // timeout!
+ throw new TimeoutException(timeSoFar);
+ else // adjust time
+ waitTime = millis - timeSoFar;
+ }
+ }
+
+ // OK.
+ enterMethod(aMeth, action);
+ }
+
+ /**
+ * This method provides the means for updating all synchronization and
+ * coordination state after the execution of a given method, and it should be
+ * called after the method is executed.
+ * In this form, only the method name is given.
+ * The synchronization state for self- and mutual-exclusion is
+ * automatically upadted.
+ */
+ public synchronized void guardedExit(String methName) {
+ guardedExit(methName, null);
+ }
+
+ /**
+ * Just like guardedExit(String methName) but with an additional
+ * coordination action that is executed.
+ * guardedExit provides the means for updating all synchronization and
+ * coordination state after the execution of a given method, and it should be
+ * called after the method is executed.
+ * In this form, the method name is given along with a coordination action.
+ * The synchronization state for self- and mutual-exclusion is
+ * automatically upadted.
+ * The given coordination action is executed.
+ */
+ public synchronized void guardedExit(String methName,
+ CoordinationAction action) {
+ Method aMeth = getOrSetMethod(methName);
+
+ for (int i = 0; i < aMeth.exes.size(); i++)
+ ((Exclusion)aMeth.exes.elementAt(i)).exitExclusion(methName);
+ if (action != null) action.doit();
+ notifyAll();
+ }
+
+ private Method getOrSetMethod(String methName) {
+ Method aMeth = null;
+ if (!methods.containsKey(methName)) {
+ methods.put(methName, (aMeth = new Method(methName)));
+ }
+ else {
+ aMeth = (Method) methods.get(methName);
+ }
+ return aMeth;
+ }
+
+ private void enterMethod(Method aMeth, CoordinationAction action) {
+ for (int i = 0; i < aMeth.exes.size(); i++)
+ ((Exclusion)aMeth.exes.elementAt(i)).enterExclusion(aMeth.name);
+
+ if (action != null) action.doit();
+ }
+
+
+
+}
+
+class Method {
+ String name;
+ Vector exes = new Vector(3);
+
+ Method(String n) {
+ name = n;
+ }
+
+ void addExclusion(Exclusion ex) {
+ exes.addElement(ex);
+ }
+
+ void removeExclusion(Exclusion ex) {
+ for (int i = 0; i < exes.size(); i++) {
+ if (exes.elementAt(i) == ex)
+ exes.removeElementAt(i);
+ }
+ }
+}
+
diff --git a/docs/dist/examples/coordination/Exclusion.java b/docs/dist/examples/coordination/Exclusion.java
new file mode 100644
index 000000000..9179cd6e0
--- /dev/null
+++ b/docs/dist/examples/coordination/Exclusion.java
@@ -0,0 +1,33 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+interface Exclusion {
+
+ boolean testExclusion(String methodName);
+
+ void enterExclusion(String methodName);
+
+ void exitExclusion(String methodName);
+
+ // for debug !!!
+ void printNames();
+}
+
diff --git a/docs/dist/examples/coordination/MethodState.java b/docs/dist/examples/coordination/MethodState.java
new file mode 100644
index 000000000..03a44378a
--- /dev/null
+++ b/docs/dist/examples/coordination/MethodState.java
@@ -0,0 +1,45 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.util.Vector;
+import java.util.Enumeration;
+
+
+class MethodState {
+
+ Vector threads=new Vector();
+
+ void enterInThread (Thread t) {
+ threads.addElement(t);
+ }
+
+ void exitInThread(Thread t) {
+ threads.removeElement(t);
+ }
+
+ boolean hasOtherThreadThan(Thread t) {
+ Enumeration e = threads.elements();
+ while (e.hasMoreElements())
+ if (e.nextElement() != t)
+ return(true);
+ return (false);
+ }
+
+}
diff --git a/docs/dist/examples/coordination/Mutex.java b/docs/dist/examples/coordination/Mutex.java
new file mode 100644
index 000000000..2472137c6
--- /dev/null
+++ b/docs/dist/examples/coordination/Mutex.java
@@ -0,0 +1,86 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+import java.lang.String;
+
+
+class Mutex implements Exclusion {
+ String[] methodNames;
+ MethodState[] methodStates;
+
+ String prettyName;
+
+ Mutex (String[] _methodNames) {
+ methodNames = _methodNames;
+ methodStates = new MethodState[methodNames.length];
+ for (int i = 0; i < methodNames.length; i++) {
+ methodStates[i] = new MethodState();
+ }
+ }
+
+ private boolean isMethodIn (String _methodName) {
+ for (int i = 0; i < methodNames.length; i++) {
+ if (_methodName.equals(methodNames[i]))
+ return(true);
+ }
+ return(false);
+ }
+
+ private MethodState getMethodState (String _methodName) {
+ for (int i = 0; i < methodNames.length; i++) {
+ if (_methodName.equals(methodNames[i]))
+ return(methodStates[i]);
+ }
+ return(null);
+ }
+
+ public boolean testExclusion (String _methodName) {
+ Thread ct = Thread.currentThread();
+ //
+ // Loop through each of the other methods in this exclusion set, to be sure
+ // that no other thread is running them. Note that we have to be careful
+ // about selfex.
+ //
+ for (int i = 0; i < methodNames.length; i++) {
+ if (!_methodName.equals(methodNames[i])) {
+ if (methodStates[i].hasOtherThreadThan(ct))
+ return(false);
+ }
+ }
+ return (true);
+ }
+
+ public void enterExclusion (String _methodName) {
+ MethodState methodState = getMethodState(_methodName);
+ methodState.enterInThread(Thread.currentThread());
+ }
+
+ public void exitExclusion (String _methodName) {
+ MethodState methodState = getMethodState(_methodName);
+ methodState.exitInThread(Thread.currentThread());
+ }
+
+ public void printNames() {
+ System.out.print("Mutex names: ");
+ for (int i = 0; i < methodNames.length; i++)
+ System.out.print(methodNames[i] + " ");
+ System.out.println();
+ }
+}
diff --git a/docs/dist/examples/coordination/Selfex.java b/docs/dist/examples/coordination/Selfex.java
new file mode 100644
index 000000000..ff73afd61
--- /dev/null
+++ b/docs/dist/examples/coordination/Selfex.java
@@ -0,0 +1,55 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+import java.lang.String;
+
+class Selfex implements Exclusion {
+ String methodName;
+ Thread thread;
+ int count = 0;
+
+ Selfex (String _methodName) {
+ methodName = _methodName;
+ }
+
+ public boolean testExclusion (String _methodName) {
+ if (count == 0)
+ return(true);
+ return (thread == Thread.currentThread());
+ }
+
+ public void enterExclusion (String _methodName) {
+ count++;
+ thread = Thread.currentThread(); // note that if count wasn't 0
+ // we aren't changing thread
+ }
+
+ public void exitExclusion (String _methodName) {
+ count--;
+ if (count == 0) // not stricly necessary, but...
+ thread = null;
+ }
+
+ public void printNames() {
+ System.out.println("Selfex name: " + methodName);
+ }
+
+}
diff --git a/docs/dist/examples/coordination/TimeoutException.java b/docs/dist/examples/coordination/TimeoutException.java
new file mode 100644
index 000000000..e16aa7f09
--- /dev/null
+++ b/docs/dist/examples/coordination/TimeoutException.java
@@ -0,0 +1,27 @@
+/* -*- Mode: Java; -*-
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package coordination;
+
+
+public class TimeoutException extends Exception {
+ long time;
+ TimeoutException(long _time) {
+ time = _time;
+ }
+}
diff --git a/docs/dist/examples/introduction/CloneablePoint.java b/docs/dist/examples/introduction/CloneablePoint.java
new file mode 100644
index 000000000..85fa4faf0
--- /dev/null
+++ b/docs/dist/examples/introduction/CloneablePoint.java
@@ -0,0 +1,42 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+*/
+package introduction;
+
+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 );
+ }
+}
diff --git a/docs/dist/examples/introduction/ComparablePoint.java b/docs/dist/examples/introduction/ComparablePoint.java
new file mode 100644
index 000000000..a2893dba0
--- /dev/null
+++ b/docs/dist/examples/introduction/ComparablePoint.java
@@ -0,0 +1,46 @@
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+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));
+ }
+}
diff --git a/docs/dist/examples/introduction/HashablePoint.java b/docs/dist/examples/introduction/HashablePoint.java
new file mode 100644
index 000000000..39eb33ba4
--- /dev/null
+++ b/docs/dist/examples/introduction/HashablePoint.java
@@ -0,0 +1,47 @@
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+import java.util.Hashtable;
+
+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));
+ }
+}
diff --git a/docs/dist/examples/introduction/Point.java b/docs/dist/examples/introduction/Point.java
new file mode 100644
index 000000000..609a0488c
--- /dev/null
+++ b/docs/dist/examples/introduction/Point.java
@@ -0,0 +1,98 @@
+/*
+ Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+ Use and copying of this software and preparation of derivative works based
+ upon this software are permitted. Any distribution of this software or
+ derivative works must comply with all applicable United States export control
+ laws.
+
+ This software is made available AS IS, and Xerox Corporation makes no warranty
+ about the software, its performance or its conformity to any specification.
+*/
+
+package introduction;
+
+public class Point {
+
+ protected double x = 0;
+ protected double y = 0;
+ protected double theta = 0;
+ protected double rho = 0;
+
+ protected boolean polar = true;
+ protected boolean rectangular = true;
+
+ public double getX(){
+ makeRectangular();
+ return x;
+ }
+
+ public double getY(){
+ makeRectangular();
+ return y;
+ }
+
+ public double getTheta(){
+ makePolar();
+ return theta;
+ }
+
+ public double getRho(){
+ makePolar();
+ return rho;
+ }
+
+ public void setRectangular(double newX, double newY){
+ x = newX;
+ y = newY;
+ rectangular = true;
+ polar = false;
+ }
+
+ public void setPolar(double newTheta, double newRho){
+ theta = newTheta;
+ rho = newRho;
+ rectangular = false;
+ polar = true;
+ }
+
+ public void rotate(double angle){
+ setPolar(theta + angle, rho);
+ }
+
+ public void offset(double deltaX, double deltaY){
+ setRectangular(x + deltaX, y + deltaY);
+ }
+
+ protected void makePolar(){
+ if (!polar){
+ theta = Math.atan2(y,x);
+ rho = y / Math.sin(theta);
+ polar = true;
+ }
+ }
+
+ protected void makeRectangular(){
+ if (!rectangular) {
+ x = rho * Math.sin(theta);
+ y = rho * Math.cos(theta);
+ rectangular = true;
+ }
+ }
+
+ public String toString(){
+ return "(" + getX() + ", " + getY() + ")["
+ + getTheta() + " : " + getRho() + "]";
+ }
+
+ public static void main(String[] args){
+ Point p1 = new Point();
+ System.out.println("p1 =" + p1);
+ p1.setRectangular(5,2);
+ System.out.println("p1 =" + p1);
+ p1.setPolar( Math.PI / 4.0 , 1.0);
+ System.out.println("p1 =" + p1);
+ p1.setPolar( 0.3805 , 5.385);
+ System.out.println("p1 =" + p1);
+ }
+}
diff --git a/docs/dist/examples/observer/Button.java b/docs/dist/examples/observer/Button.java
new file mode 100644
index 000000000..086a89e24
--- /dev/null
+++ b/docs/dist/examples/observer/Button.java
@@ -0,0 +1,45 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+Button.java
+
+*/
+
+
+package observer;
+
+import java.awt.Color;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+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() {}
+
+}
diff --git a/docs/dist/examples/observer/ColorLabel.java b/docs/dist/examples/observer/ColorLabel.java
new file mode 100644
index 000000000..7b0c05fc9
--- /dev/null
+++ b/docs/dist/examples/observer/ColorLabel.java
@@ -0,0 +1,40 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+ColorLabel.java
+
+*/
+
+package observer;
+import java.awt.Color;
+import java.awt.Label;
+
+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);
+ }
+}
+
+
diff --git a/docs/dist/examples/observer/Demo.java b/docs/dist/examples/observer/Demo.java
new file mode 100644
index 000000000..b25552478
--- /dev/null
+++ b/docs/dist/examples/observer/Demo.java
@@ -0,0 +1,34 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+Demo.java
+
+*/
+
+package observer;
+
+public class Demo {
+ public static void main(String[] args) {
+
+ Display display = new Display();
+ Button b1 = new Button(display);
+ Button b2 = new Button(display);
+ ColorLabel c1 = new ColorLabel(display);
+ ColorLabel c2 = new ColorLabel(display);
+ ColorLabel c3 = new ColorLabel(display);
+
+ b1.addObserver(c1);
+ b1.addObserver(c2);
+ b2.addObserver(c3);
+ }
+}
+
diff --git a/docs/dist/examples/observer/Display.java b/docs/dist/examples/observer/Display.java
new file mode 100644
index 000000000..d7f4d479c
--- /dev/null
+++ b/docs/dist/examples/observer/Display.java
@@ -0,0 +1,52 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+Display.java
+
+*/
+
+package observer;
+import java.awt.Frame;
+import java.awt.Panel;
+import java.awt.Container;
+import java.awt.Component;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.BorderLayout;
+
+/*
+ * Display is the container class that holds all the views of the
+ * colored number.
+ * In this demo, it holds buttons.
+ */
+
+class Display extends Panel {
+
+ protected Frame frame = new Frame("Subject/Observer Demo");
+
+ Display() {
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {System.exit(0);}
+ });
+
+ frame.add(this, BorderLayout.CENTER);
+ frame.pack();
+ frame.setVisible(true);
+ }
+
+ void addToFrame(Component c) {
+ add(c);
+ frame.pack();
+ }
+}
+
+
diff --git a/docs/dist/examples/observer/Observer.java b/docs/dist/examples/observer/Observer.java
new file mode 100644
index 000000000..58ae44916
--- /dev/null
+++ b/docs/dist/examples/observer/Observer.java
@@ -0,0 +1,22 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+Observer.java
+
+*/
+package observer;
+
+interface Observer {
+ void setSubject(Subject s);
+ Subject getSubject();
+ void update();
+}
diff --git a/docs/dist/examples/observer/Subject.java b/docs/dist/examples/observer/Subject.java
new file mode 100644
index 000000000..5d80b1e09
--- /dev/null
+++ b/docs/dist/examples/observer/Subject.java
@@ -0,0 +1,24 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+Subject.java
+
+*/
+package observer;
+import java.util.Vector;
+
+interface Subject {
+ void addObserver(Observer obs);
+ void removeObserver(Observer obs);
+ Vector getObservers();
+ Object getData();
+}
diff --git a/docs/dist/examples/observer/SubjectObserverProtocol.java b/docs/dist/examples/observer/SubjectObserverProtocol.java
new file mode 100644
index 000000000..73f730e09
--- /dev/null
+++ b/docs/dist/examples/observer/SubjectObserverProtocol.java
@@ -0,0 +1,47 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+SubjectObserverProtocol.java
+
+*/
+
+package observer;
+
+import java.util.Vector;
+
+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; }
+
+}
+
diff --git a/docs/dist/examples/observer/SubjectObserverProtocolImpl.java b/docs/dist/examples/observer/SubjectObserverProtocolImpl.java
new file mode 100644
index 000000000..01f0c38fc
--- /dev/null
+++ b/docs/dist/examples/observer/SubjectObserverProtocolImpl.java
@@ -0,0 +1,36 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+SubjectObserverProtocolImpl.java
+
+*/
+
+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());
+
+}
+
diff --git a/docs/dist/examples/spacewar/Bullet.java b/docs/dist/examples/spacewar/Bullet.java
new file mode 100644
index 000000000..6581dbbf7
--- /dev/null
+++ b/docs/dist/examples/spacewar/Bullet.java
@@ -0,0 +1,48 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Bullet.java
+Part of the Spacewar game.
+
+*/
+
+package spacewar;
+
+class Bullet extends SpaceObject {
+
+ static private final int SIZE = 3; //Can't be changed for now!!!
+ static private int LIFETIME = 50;
+
+ private int lifeLeft;
+
+ Bullet (Game theGame, double xP, double yP, double xV, double yV) {
+ super(theGame, xP, yP, xV, yV);
+ lifeLeft = LIFETIME;
+ }
+
+ int getSize() { return SIZE; }
+
+ void handleCollision(SpaceObject obj) {
+ die();
+ }
+
+ void clockTick() {
+ if (--lifeLeft == 0)
+ die();
+ super.clockTick();
+ }
+}
diff --git a/docs/dist/examples/spacewar/Debug.java b/docs/dist/examples/spacewar/Debug.java
new file mode 100644
index 000000000..b9a476e0e
--- /dev/null
+++ b/docs/dist/examples/spacewar/Debug.java
@@ -0,0 +1,219 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Debug.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Menu;
+import java.awt.CheckboxMenuItem;
+import java.awt.Frame;
+import java.awt.TextArea;
+import java.awt.Dimension;
+
+/**
+ * This aspect specifies debugging information to be output to the
+ * information window.
+ *
+ * When the debug aspect is compiled in the Frame menu has several checkbox
+ * items that can be used to control the amount of tracing information
+ * displayed. (By default the first three are off, because they generate
+ * so much information.)
+ *
+ * There are two reasons to gather all this debugging code into an aspect
+ * like this:
+ *
+ * (1) It makes it easier to understand when it is all in one place.
+ *
+ * (2) It means that we can "plug and debug". We can enable/disable
+ * the debugging code simply by weaving or not weaving this
+ * aspect in.
+ *
+ * All in all, this is a lot better than the usual practice of writing
+ * complex debugging code and then deleting it when the bug is found,
+ * only to regret it a month later when a related bug surfaces. (Or even
+ * the same bug!)
+ *
+ * This file also defines a class InfoWin, which it uses to display all the
+ * debugging information.
+ */
+aspect Debug {
+
+ private static InfoWin infoWin = new InfoWin();
+
+ private static Menu menu = new Menu("Debug");
+
+ private static CheckboxMenuItem traceConstructors =
+ new CheckboxMenuItem("trace constructors", false);
+ private static CheckboxMenuItem traceInitializations =
+ new CheckboxMenuItem("trace initializations", false);
+ private static CheckboxMenuItem traceMethods =
+ new CheckboxMenuItem("trace methods", false);
+ private static CheckboxMenuItem traceClockTick =
+ new CheckboxMenuItem("trace clock tick", false);
+ private static CheckboxMenuItem traceRegistry =
+ new CheckboxMenuItem("trace registry", true);
+ private static CheckboxMenuItem traceFireCollideDamage =
+ new CheckboxMenuItem("trace fire, collide, damage", true);
+
+ after() returning (SWFrame frame): call(SWFrame+.new(..)) {
+ menu.add(traceConstructors);
+ menu.add(traceInitializations);
+ menu.add(traceMethods);
+ menu.add(traceClockTick);
+ menu.add(traceRegistry);
+ menu.add(traceFireCollideDamage);
+ frame.getMenuBar().add(menu);
+ }
+
+ /*
+ * all constructors
+ */
+ pointcut allConstructorsCut():
+ call((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ after(): allConstructorsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done constructing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * All dynamic initializations
+ */
+ pointcut allInitializationsCut():
+ initialization((spacewar.* && !(Debug+ || InfoWin+)).new(..));
+
+ before(): allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("begin initializing " + thisJoinPoint.getSignature());
+ }
+ }
+ after(): allInitializationsCut() {
+ if (traceConstructors.getState()) {
+ infoWin.println("done initializing " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * all methods
+ */
+ pointcut allMethodsCut():
+ execution(* (spacewar.* && !(Debug+ || InfoWin+)).*(..));
+
+ before(): allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("entering " + thisJoinPoint.getSignature());
+ }
+ }
+ after(): allMethodsCut() {
+ if (traceMethods.getState()) {
+ infoWin.println("exiting " + thisJoinPoint.getSignature());
+ }
+ }
+
+ /*
+ * clock ticks
+ */
+ after(Object obj):
+ (target(obj) && (target(Game) ||
+ target(Registry) ||
+ target(SpaceObject)))
+ && call(void clockTick()) {
+ if (traceClockTick.getState())
+ infoWin.println("ticking " + obj);
+ }
+
+ /*
+ * registry contents
+ */
+ after(Registry registry):
+ target(registry) && (call(void register(..)) ||
+ call(void unregister(..))) {
+ if (traceRegistry.getState())
+ infoWin.println(registry.getTable().size() +
+ " space objects in the registry.");
+ }
+
+ /*
+ * fire, collide, damage
+ */
+ after(): call(void Ship.fire()) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println("firing");
+ }
+
+ after(Ship ship, SpaceObject obj):
+ call(void Ship.handleCollision(SpaceObject)) && target(ship) && args(obj) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(ship + " collides with " + obj);
+ }
+
+ after(Ship shipA, Ship shipB):
+ execution(void Ship.bounce(Ship, Ship)) && args(shipA, shipB) {
+ if (traceFireCollideDamage.getState())
+ infoWin.println(shipA + " bounces with " + shipB);
+ }
+
+ before(Ship ship, double amount):
+ call(void Ship.inflictDamage(double)) && target(ship) && args(amount) {
+ if (traceFireCollideDamage.getState())
+ if (amount > 0)
+ infoWin.println(ship + "gets " +
+ amount + " damage (" +
+ ship.getDamage() + ")");
+ }
+
+}
+
+class InfoWin {
+ private Frame frame;
+ private TextArea info;
+
+ InfoWin() {
+ frame = new Frame("debugging info for spacewar game");
+ info = new TextArea();
+ info.setEditable(false);
+
+ Dimension screenSize = frame.getToolkit().getScreenSize();
+ frame.setSize(250, 600);
+ frame.setLocation(screenSize.width - 250, 0);
+ frame.add(info);
+ frame.show();
+ frame.toFront();
+ }
+
+ void clear() {
+ info.setText("");
+ }
+
+ void println(String line) {
+ info.append(line + "\n");
+ }
+
+ void print(String line) {
+ info.append(line);
+ }
+}
diff --git a/docs/dist/examples/spacewar/Display.java b/docs/dist/examples/spacewar/Display.java
new file mode 100644
index 000000000..a0f77b347
--- /dev/null
+++ b/docs/dist/examples/spacewar/Display.java
@@ -0,0 +1,166 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.awt.Graphics;
+import java.awt.Canvas;
+import java.awt.Image;
+import java.awt.event.KeyListener;
+
+/**
+ * The display aspects capture the look and feel of the Game in modular
+ * pluggable units.
+ *
+ * The model is that constructing a concrete subclass of Display attaches that
+ * kind of display to the game. It will Display the game as it goes along.
+ * A game can have any number of displays. Any of the displays will accept
+ * keyboard input.
+ *
+ */
+
+class Display extends Canvas {
+
+ private static Vector DISPLAYS = new Vector(2);
+ private static Vector PLAYERS = new Vector(2);
+ private static Pilot pilot1, pilot2;
+
+ Game game;
+ SWFrame frame;
+ Image offImage;
+ Graphics offGraphics;
+
+ Game getGame() { return game; }
+ static Pilot getPilot1() { return pilot1; }
+ static Pilot getPilot2() { return pilot2; }
+
+ Display(Game g) {
+ super();
+ game = g;
+
+ frame = new SWFrame(game, this);
+ DISPLAYS.addElement(this);
+ }
+
+
+ void noticeSizeChange() {
+ initializeOffImage();
+ }
+
+ private void initializeOffImage () {
+ int w = getSize().width;
+ int h = getSize().height;
+ if ( w > 0 & h > 0) {
+ offImage = createImage(w, h);
+ offGraphics = offImage.getGraphics();
+ }
+ }
+
+ /*
+ * In our double buffering scheme, painting just means copying the buffer
+ * to the screen. The Display aspect draws into the buffer.
+ */
+ public void paint(Graphics g) {
+ if (offImage != null)
+ g.drawImage(offImage, 0, 0, null);
+ }
+
+ public void update(Graphics g) {
+ /*
+ * There are 4 steps to this:
+ * - clear the double buffer
+ * - paint the objects into the double buffer
+ * - paint the status into the double buffer
+ * - paint the doublebuffer into the buffer
+ */
+ offGraphics.setColor(getBackground());
+ offGraphics.fillRect(0, 0, getBounds().width, getBounds().height);
+ paintObjects(offGraphics);
+ paintStatus(offGraphics);
+ g.drawImage(offImage, 0, 0, null);
+ }
+
+ void paintObjects(Graphics g) { }
+ void paintStatus(Graphics g) {}
+
+ static aspect DisplayAspect {
+
+ after (String mode) returning (Game game): call(Game+.new(String)) && args(mode) {
+ new Display1(game);
+ new Display2(game);
+
+ if ( mode.equals("1") ) {
+ pilot1 = game.newPlayer(1);
+ }
+ else if ( mode.equals("2") ) {
+ pilot1 = game.newPlayer(1);
+ pilot2 = game.newPlayer(2);
+ }
+ else if (mode. equals("demo")) {
+ pilot1 = game.newRobot(1);
+ pilot2 = game.newRobot(2);
+ } else {
+ game.error("Invalid mode: " + mode);
+ game.quit();
+ }
+ }
+
+
+ /*
+ * I'm not really sure this belongs here.
+ *
+ * Being here what it does is makes the Display aspect
+ * responsible for having the Players couple up to it. That's
+ * kind of nice, but its a bit incomplete, since Player is
+ * really part of the GUI, not part of the core Game.
+ *
+ * In a future re-factoring this will get worked out better.
+ * What will happen is that GUI will be an aspect that has the
+ * core GUI. Each of the different kinds of displays will be
+ * aspects that tie themselves in.
+ */
+ after () returning (Player player): call(Player+.new(..)) {
+ Enumeration elements = DISPLAYS.elements();
+ while ( elements.hasMoreElements() ) {
+ Display display = (Display)elements.nextElement();
+ display.addKeyListener(player);
+ }
+ }
+
+ after() returning (Display display): call(Display+.new(..)) {
+ display.noticeSizeChange();
+ }
+
+ after(Display display) returning (): call(void setSize(..)) && target(display) {
+ display.noticeSizeChange();
+ }
+
+ after(): call(void Game.clockTick()) {
+ Enumeration elements = DISPLAYS.elements();
+ while ( elements.hasMoreElements() ) {
+ Display display = (Display)elements.nextElement();
+ display.repaint();
+ }
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/Display1.java b/docs/dist/examples/spacewar/Display1.java
new file mode 100644
index 000000000..484a2342a
--- /dev/null
+++ b/docs/dist/examples/spacewar/Display1.java
@@ -0,0 +1,203 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display1.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.awt.Graphics;
+import java.awt.Color;
+import java.util.Random;
+
+/**
+ * This is the standard display aspect.
+ */
+class Display1 extends Display {
+ /*
+ * Here's the color scheme for the game. No other places in this file
+ * should say Color.xxx. Instead, that color should be given a symbolic
+ * name here.
+ */
+ private static Color backgroundColor = Color.black;
+ private static Color player1ShipColor = Color.white;
+ private static Color player2ShipColor = Color.gray;
+ private static Color robotShipColor = new Color(0xa00000);
+ private static Color flameColor = Color.red;
+ private static Color shipExplosionColor = Color.red;
+ private static Color bulletColor = Color.green;
+ private static Color energyPacketOuterColor = Color.blue;
+ private static Color energyPacketInnerColor = new Color(0x7070FF);
+ private static Color statusLabelsColor = Color.white;
+ private static Color statusMeterBorderColor = Color.white;
+ private static Color energyStatusMeterColor = Color.blue;
+ private static Color damageStatusMeterColor = Color.red;
+
+
+ Display1(Game game) {
+ super(game);
+ frame.setLocation(20, 20);
+ }
+
+ void noticeSizeChange() {
+ super.noticeSizeChange();
+ setBackground(backgroundColor);
+ }
+
+ void paintObjects(Graphics g) {
+ SpaceObject[] objects = game.getRegistry().getObjects();
+ final int len = objects.length;
+ for (int i = 0; i < len; i++) {
+ objects[i].paint(g);
+ }
+ }
+
+ static aspect SpaceObjectPainting {
+
+ abstract private void SpaceObject.paint(Graphics g);
+
+ /*
+ * Ships are by far and away the most complex of the space Objects
+ * to paint. First off, we need to set the color when the ship
+ * is made.
+ */
+ private Color Ship.color;
+
+ after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
+ if (pilot.getNumber() == 1)
+ ship.color = player1ShipColor;
+ else if (pilot.getNumber() == 2)
+ ship.color = player2ShipColor;
+ else
+ ship.color = robotShipColor;
+ }
+
+ private void Ship.paint(Graphics g) {
+ final double PI = Math.PI;
+ int[] radius = {15, 12, -4, 12, -9, -15, -9};
+ double[] angle = {0, PI * 3/4, 0, -PI * 3/4, PI/8, 0, -PI/8};
+ int[] x;
+ int[] y;
+
+ Random random = new Random();
+
+ if (this.getDamage() >= this.MAX_DAMAGE) {
+ int lines = 20;
+ x = new int[lines];
+ y = new int[lines];
+ g.setColor(shipExplosionColor);
+ for (int i = 0; i < lines; i++) {
+ x[i] = (int)(this.getXPos()) + random.nextInt() % 20;
+ y[i] = (int)(this.getYPos()) + random.nextInt() % 20;
+ }
+ for (int i = 0; i < lines; i++)
+ g.drawLine(x[i], y[i], x[(i + 1) % lines], y[(i + 1) % lines]);
+ } else {
+ x = new int[7];
+ y = new int[7];
+
+ g.setColor(this.color);
+
+ radius[5] += random.nextInt() % 3;
+ // convert coordinates from polar to cartesian
+ for (int i = 0; i < 7; i++) {
+ x[i] = (int)
+ (this.getXPos() +
+ Math.cos(this.getOrientation() + angle[i]) * radius[i]);
+ y[i] = (int)
+ (this.getYPos() +
+ Math.sin(this.getOrientation() + angle[i]) * radius[i]);
+ }
+
+ // draw the body as a polygon
+ g.drawPolygon(x, y, 4);
+
+ // if the ship is accelerating, draw in a flame
+ if (this.getRAcc() != 0) {
+ g.setColor(flameColor);
+ g.drawLine(x[4], y[4], x[5], y[5]);
+ g.drawLine(x[5], y[5], x[6], y[6]);
+ }
+ }
+ }
+
+ /*
+ * Bullets
+ */
+ private void Bullet.paint(Graphics g) {
+ g.setColor(bulletColor);
+ g.fillOval((int)this.getXPos() - 1,
+ (int)this.getYPos() - 1,
+ 3,
+ 3);
+ }
+
+ /*
+ * energy packets
+ */
+ private void EnergyPacket.paint(Graphics g) {
+ g.setColor(energyPacketOuterColor);
+ g.fillOval((int)this.getXPos() - 5,
+ (int)this.getYPos() - 5,
+ 10, 10);
+ g.setColor(energyPacketInnerColor);
+ g.fillOval((int)this.getXPos() - 2,
+ (int)this.getYPos() - 2,
+ 3, 3);
+ }
+ }
+
+
+ void paintStatus(Graphics g) {
+ int left1 = 60;
+ int top1 = 0;
+
+ int left2 = 200;
+ int top2 = 0;
+
+ g.setColor(statusLabelsColor);
+ g.drawString("energy:", 5, top1 + 15);
+ g.drawString("damage:", 5, top1 + 30);
+
+ if (getPilot1() != null)
+ paintLevels(g, getPilot1().getShip(), top1, left1);
+ if (getPilot2() != null)
+ paintLevels(g, getPilot2().getShip(), top2, left2);
+ }
+
+ static void paintLevels(Graphics g, Ship ship, int top, int left) {
+ if (ship == null)
+ return;
+ else if (ship.isAlive()) {
+ g.setColor(statusMeterBorderColor);
+ g.drawRect(left, top + 6, 101, 10);
+ g.drawRect(left, top + 21, 101, 10);
+ g.setColor(energyStatusMeterColor);
+ g.fillRect(left + 1, top + 7, (int)(ship.getEnergyLevel()*100), 9);
+ g.setColor(damageStatusMeterColor);
+ g.fillRect(left + 1, top + 22, (int)(ship.getDamageLevel()*100), 9);
+ }
+ else {
+ g.setColor(damageStatusMeterColor);
+ g.drawString("Ship is destroyed", left+1, top+15);
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/Display2.java b/docs/dist/examples/spacewar/Display2.java
new file mode 100644
index 000000000..d2dbeb40e
--- /dev/null
+++ b/docs/dist/examples/spacewar/Display2.java
@@ -0,0 +1,138 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Display2.java
+Part of the Spacewar system.
+*/
+
+package spacewar;
+
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.awt.Graphics;
+import java.awt.Color;
+
+
+/**
+ * This is the cheap Display aspect.
+ */
+class Display2 extends Display {
+
+ Display2(Game game) {
+ super(game);
+ frame.setLocation(540, 20);
+ }
+
+ void noticeSizeChange() {
+ super.noticeSizeChange();
+ setBackground(Color.darkGray);
+ }
+
+ void paintObjects(Graphics g) {
+ SpaceObject[] objects = game.getRegistry().getObjects();
+ final int len = objects.length;
+ for (int i = 0; i < len; i++) {
+ objects[i].paint(g);
+ }
+ }
+
+ static aspect SpaceObjectPainting {
+
+ abstract private void SpaceObject.paint(Graphics g);
+
+ /*
+ * Ships are by far and away the most complex of the space Objects
+ * to paint.
+ */
+ private Color Ship.color;
+
+ after(Pilot pilot) returning (Ship ship): call(Ship Game.newShip(Pilot)) && args(pilot) {
+ if (pilot.getNumber() == 1)
+ ship.color = Color.white;
+ else if (pilot.getNumber() == 2)
+ ship.color = Color.gray;
+ else
+ ship.color = new Color(0xa00000);
+ }
+
+ private void Ship.paint(Graphics g) {
+ if (this.getDamage() < this.MAX_DAMAGE) {
+ double x = this.getXPos();
+ double y = this.getYPos();
+ double sinTheta = Math.sin(this.getOrientation());
+ double cosTheta = Math.cos(this.getOrientation());
+
+ g.setColor(color);
+ g.drawLine((int)(x + 8*cosTheta), (int)(y + 8*sinTheta),
+ (int)(x - 8*cosTheta), (int)(y - 8*sinTheta));
+
+ // if the ship is accelerating, draw thruster
+ if (this.getRAcc() != 0) {
+ g.setColor(Color.red);
+ g.fillOval((int)(x - 8*cosTheta), (int)(y - 8*sinTheta), 6, 6);
+ }
+ }
+ }
+
+ private void Bullet.paint(Graphics g) {
+ g.setColor(Color.green);
+ g.fillOval((int)this.getXPos() - 1,
+ (int)this.getYPos() - 1,
+ 3,
+ 3);
+ }
+
+ private void EnergyPacket.paint(Graphics g) {
+ g.setColor(Color.white);
+ g.fillOval((int)this.getXPos() - 5,
+ (int)this.getYPos() - 5,
+ 10,
+ 10);
+ }
+ }
+
+ void paintStatus(Graphics g) {
+ int left1 = 60;
+ int top1 = 0;
+
+ int left2 = 200;
+ int top2 = 0;
+
+ g.setColor(Color.white);
+ g.drawString("energy:", 5, top1 + 15);
+ g.drawString("damage:", 5, top1 + 30);
+
+ if (getPilot1() != null)
+ paintLevels(g, getPilot1().getShip(), top1, left1);
+ if (getPilot2() != null)
+ paintLevels(g, getPilot2().getShip(), top2, left2);
+ }
+
+ void paintLevels(Graphics g, Ship ship, int top, int left) {
+ if (ship == null)
+ return;
+ else if (ship.isAlive()) {
+ g.drawString(Float.toString(ship.getEnergyLevel()*100), left+1, top+15);
+ g.drawString(Float.toString(ship.getDamageLevel()*100), left+1, top+30);
+ }
+ else {
+ g.setColor(Color.red);
+ g.drawString("Ship is destroyed", left+1, top+15);
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/EnergyPacket.java b/docs/dist/examples/spacewar/EnergyPacket.java
new file mode 100644
index 000000000..d7bc4f9ec
--- /dev/null
+++ b/docs/dist/examples/spacewar/EnergyPacket.java
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+EnergyPacket.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+class EnergyPacket extends SpaceObject {
+
+ static private final int SIZE = 5; //Can't be changed for now!!!
+ int getSize() { return SIZE; }
+
+ private double energy;
+
+ double getEnergy() { return energy; }
+
+ EnergyPacket(Game theGame,
+ double xP, double yP, double xV, double yV, double e) {
+ super(theGame, xP, yP, xV, yV);
+ energy = e;
+ }
+
+ void handleCollision(SpaceObject obj) {
+ die();
+ }
+}
diff --git a/docs/dist/examples/spacewar/EnergyPacketProducer.java b/docs/dist/examples/spacewar/EnergyPacketProducer.java
new file mode 100644
index 000000000..efd276042
--- /dev/null
+++ b/docs/dist/examples/spacewar/EnergyPacketProducer.java
@@ -0,0 +1,63 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+EnergyPacketProducer.java
+Part of the Spacewar system.
+
+ This implementation creates booby-trapped packets 20% of the time.
+
+*/
+
+package spacewar;
+
+
+class EnergyPacketProducer extends Thread {
+ private final static int MIN = -20;
+ private final static int MAX = 80;
+ private final static int EXPECTEDINTERVAL = 15;
+
+ private Game game;
+
+ Game getGame() { return game; }
+
+ EnergyPacketProducer(Game theGame) {
+ super("EnergyPacketProducer");
+ game = theGame;
+ }
+
+ public void run() {
+ while(true) {
+ produceAPacket();
+ waitForABit();
+ }
+ }
+
+ void waitForABit() {
+ try { Thread.sleep((int)(Math.random() * EXPECTEDINTERVAL * 2000)); }
+ catch (InterruptedException e) {}
+ }
+
+ void produceAPacket() {
+ EnergyPacket pkt =
+ new EnergyPacket(game,
+ Math.random() * getGame().getWidth(),
+ Math.random() * getGame().getHeight(),
+ Math.random() * 2 - 1,
+ Math.random() * 2 - 1,
+ Math.random() * (MAX - MIN) + MIN);
+ }
+}
diff --git a/docs/dist/examples/spacewar/EnsureShipIsAlive.java b/docs/dist/examples/spacewar/EnsureShipIsAlive.java
new file mode 100644
index 000000000..f7b949a92
--- /dev/null
+++ b/docs/dist/examples/spacewar/EnsureShipIsAlive.java
@@ -0,0 +1,35 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Ship.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+/**
+ * This aspect makes sure that the ship is alive before performing any console
+ * commands.
+ *
+ */
+aspect EnsureShipIsAlive {
+ void around (Ship ship): Ship.helmCommandsCut(ship) {
+ if ( ship.isAlive() ) {
+ proceed(ship);
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/Game.java b/docs/dist/examples/spacewar/Game.java
new file mode 100644
index 000000000..da67d7bc3
--- /dev/null
+++ b/docs/dist/examples/spacewar/Game.java
@@ -0,0 +1,215 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Game.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Dimension;
+
+/**
+ * The Game class is the root of the spacewar game. To start a spacewar
+ * game, you can either call the main method, or instantiate this class
+ * directly.
+ *
+ * Synchronization is done by the GameSynchronization aspect.
+ */
+public class Game extends Thread {
+
+ /**
+ * To run the game from top level, simply say Java Game, as usual. Passing
+ * an argument makes the game run in demo mode. Without an argument it runs
+ * in the normal player mode.
+ */
+ public static void main(String[] args) {
+ if ( args.length == 0 )
+ new Game("1").run();
+ new Game(args[0]).run();
+ }
+
+
+ private Timer timer;
+ private EnergyPacketProducer ePP;
+
+ private Registry registry;
+ private Pilot pilot1, pilot2;
+
+ private Dimension screenSize = new Dimension(500, 500);
+
+ Registry getRegistry() { return registry; }
+ Pilot getPilot1() { return pilot1; }
+ Pilot getPilot2() { return pilot2; }
+
+ /** returns the width of the screen, delegating to screenSize */
+ int getWidth() { return screenSize.width; }
+
+ /** returns the height of the screen, delegating to screenSize */
+ int getHeight() { return screenSize.height; }
+
+ /**
+ * To run the game, simply instantiate this class. It runs in its own
+ * thread. You can instantiate multiple games at once. For the time being
+ * the only way to end the game is to exit from the Java VM.
+ *
+ * @param isDemo Controls whether the game runs in demo mode or not. True
+ * means it is a demo, false means it runs in normal 2 player mode.
+ */
+ public Game(String mode) {
+ timer = new Timer(this);
+ ePP = new EnergyPacketProducer(this);
+ registry = new Registry(this);
+ }
+
+ public void run() {
+ timer.start();
+ ePP.start();
+
+ while(true) {
+ try {
+ newRobot(3);
+ Thread.sleep(15000);
+ }
+ catch (InterruptedException e) {}
+ }
+ }
+
+
+ /**
+ * add a robot to the game. This is a menu command.
+ */
+ void addRobot() {
+ newRobot(3);
+ }
+
+ /**
+ * resurrect the ships in the game. This is a menu command.
+ */
+ void resetShips() {
+ Ship[] ships = registry.getShips();
+
+ for (int i = 0; i < ships.length; i++) {
+ Ship ship = ships[i];
+ Pilot pilot = ship.getPilot();
+ newShip(pilot);
+ }
+ }
+
+ /**
+ * leave the game. This is a menu command.
+ */
+ void quit() {
+ System.exit(0);
+ }
+
+ void error(Object o) {
+ System.err.println(o);
+ }
+
+
+ /**
+ * returns a new player. With {@link #newRobot} and {@link
+ * #newShip}, the only ways to make a Player, a Robot, or a Ship.
+ * The structural invariant is that there should be no calls to
+ * new of one of these three classes outside these three methods.
+ */
+ Player newPlayer(int number) {
+ Player player = new Player(this, number);
+ newShip(player);
+ return player;
+ }
+
+ /**
+ * returns a new robot. With {@link #newPlayer} and {@link
+ * #newShip}, the only ways to make a Player, a Robot, or a Ship.
+ * The structural invariant is that there should be no calls to
+ * new of one of these three classes outside these three methods.
+ */
+ Robot newRobot(int number) {
+ Robot robot = new Robot(this, number);
+ newShip(robot);
+ robot.start();
+ return robot;
+ }
+
+ /**
+ * returns a new ship. With {@link #newRobot} and {@link
+ * #newPlayer}, the only ways to make a Player, a Robot, or a
+ * Ship. The structural invariant is that there should be no
+ * calls to new of one of these three classes outside these three
+ * methods.
+ */
+ Ship newShip(Pilot pilot) {
+ //
+ // If there is an old ship (we're doing a reset), then remove it from
+ // the registry.
+ //
+ Ship oldShip = pilot.getShip();
+ if (! (oldShip == null))
+ oldShip.die();
+
+ Ship newShip = new Ship(this,
+ Math.random() * getWidth(),
+ Math.random() * getHeight(),
+ Math.random() * Math.PI * 2);
+ pilot.setShip(newShip);
+ newShip.setPilot(pilot);
+
+ return newShip;
+ }
+
+ void clockTick() {
+ registry.clockTick();
+ handleCollisions();
+ }
+
+ // collision detection
+
+ void handleCollisions() {
+ SpaceObject[] objects = registry.getObjects();
+
+ SpaceObject objI, objJ;
+ for (int i = 0; i < objects.length; i++) {
+ objI = objects[i];
+ for (int j = i + 1; j < objects.length; j++) {
+ objJ = objects[j];
+ if (objI instanceof Bullet && objJ instanceof Bullet)
+ continue;
+ if (isCollision(objI, objJ)) {
+ if (objI instanceof Ship && objJ instanceof Ship)
+ Ship.bounce((Ship)(objI), (Ship)(objJ));
+ else {
+ objI.handleCollision(objJ);
+ objJ.handleCollision(objI);
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Is the distance between the two centers less than the sum of the two
+ * radii. This is a cheap and dirty (i.e. wrong) implementation of this.
+ */
+ static boolean isCollision(SpaceObject a, SpaceObject b) {
+ return (Math.abs(a.getXPos() - b.getXPos()) +
+ Math.abs(a.getYPos() - b.getYPos())) <
+ (a.getSize()/2 + b.getSize()/2);
+ }
+}
diff --git a/docs/dist/examples/spacewar/GameSynchronization.java b/docs/dist/examples/spacewar/GameSynchronization.java
new file mode 100644
index 000000000..dcf42e904
--- /dev/null
+++ b/docs/dist/examples/spacewar/GameSynchronization.java
@@ -0,0 +1,54 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+RegistrySynchronization.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import coordination.Coordinator;
+
+/**
+ * This aspect ensures synchronized access to methods of the Game in the
+ * presence of several threads.
+ *
+ * It uses the Coordinator class, from the AspectJ coordination library.
+ * (This case is right on the borderline of being too simple to use the
+ * coordination library, but we use it anyways to keep the similarity
+ * with the RegistrySynchronizer.)
+ *
+ * It uses a per-Game coordination scheme, so there is one instance of
+ * this class for each instance of the Game class. When this class is
+ * constructed, it registers appropriate mutexes and selfexes using
+ * the behavior inherited from Coordinator.
+ *
+ * The coordination constraints for the Game are simple. We just need to
+ * make sure that newShip and handleCollisions are mutually exclusive. That
+ * ensures that they we can't destroy a ship that has just been replaced.
+ */
+aspect GameSynchronization extends Coordinator perthis(this(Game)) {
+
+ protected pointcut synchronizationPoint():
+ call(void Game.handleCollisions(..)) || call(Ship Game.newShip(..));
+
+ public GameSynchronization() {
+ addMutex(new String[] {"handleCollisions", "newShip"});
+ }
+
+}
diff --git a/docs/dist/examples/spacewar/Makefile b/docs/dist/examples/spacewar/Makefile
new file mode 100644
index 000000000..108d3c8c4
--- /dev/null
+++ b/docs/dist/examples/spacewar/Makefile
@@ -0,0 +1,12 @@
+SHELL=bash
+ACJOPTS=-verbose -nosymbols
+AJC=ajc
+
+.PHONY: demo debug
+
+demo:
+ $(AJC) $(ACJOPTS) @demo.lst
+
+debug:
+ $(AJC) $(ACJOPTS) @debug.lst
+
diff --git a/docs/dist/examples/spacewar/Pilot.java b/docs/dist/examples/spacewar/Pilot.java
new file mode 100644
index 000000000..330d860bf
--- /dev/null
+++ b/docs/dist/examples/spacewar/Pilot.java
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+*/
+
+package spacewar;
+
+
+/**
+ * Pilot is the abstract superclass of Player and Robot.
+ *
+ */
+
+abstract class Pilot {
+ private Game game;
+ private int number;
+ protected Ship ship = null;
+
+ Game getGame() { return game; }
+ int getNumber() { return number; }
+ Ship getShip() { return ship; }
+
+ void setShip(Ship s) { ship = s; }
+
+ Pilot (Game g, int n) {
+ super();
+ game = g;
+ number = n;
+ }
+}
diff --git a/docs/dist/examples/spacewar/Player.java b/docs/dist/examples/spacewar/Player.java
new file mode 100644
index 000000000..ebde6d5c4
--- /dev/null
+++ b/docs/dist/examples/spacewar/Player.java
@@ -0,0 +1,122 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+*/
+
+package spacewar;
+
+import java.util.Enumeration;
+import java.awt.event.KeyListener;
+import java.awt.event.KeyEvent;
+
+class Player extends Pilot implements KeyListener {
+
+ private KeyMapping keyMapping;
+
+ /** current rotation key */
+ private int rotation_direction = Ship.STOP; // current rotation key
+
+ /** current thrust */
+ private boolean thrust_on = false;
+
+ Player(Game theGame, int number) {
+ super(theGame,number);
+
+ if (getNumber() == 1)
+ keyMapping = KeyMapping.keyMapping1;
+ else if (getNumber() == 2)
+ keyMapping = KeyMapping.keyMapping2;
+
+ }
+
+ public void keyPressed(KeyEvent e) {
+ int keyCode = e.getKeyCode();
+ boolean consumed = true;
+
+ if (keyCode == keyMapping.fire) {
+ ship.fire();
+ }
+ else if (keyCode == keyMapping.thrust && !thrust_on) {
+ ship.thrust(true);
+ thrust_on = true;
+ }
+ else if (keyCode == keyMapping.right &&
+ rotation_direction != Ship.COUNTERCLOCKWISE) {
+ //start rotating clockwise unless already rotating in the
+ //opposite direction
+ rotation_direction = Ship.CLOCKWISE;
+ ship.rotate(Ship.CLOCKWISE);
+ }
+ else if (keyCode == keyMapping.left &&
+ rotation_direction != Ship.CLOCKWISE) {
+ //start rotating counterclockwise unless already rotating in the
+ //opposite direction
+ rotation_direction = Ship.COUNTERCLOCKWISE;
+ ship.rotate(Ship.COUNTERCLOCKWISE);
+ }
+ else {
+ consumed = false;
+ }
+
+ if (consumed) e.consume();
+ }
+
+ public void keyReleased(KeyEvent e) {
+ int keyCode = e.getKeyCode();
+
+ if (keyCode == keyMapping.thrust) {
+ ship.thrust(false); //engine off
+ thrust_on = false;
+ }
+ else if (keyCode == keyMapping.right &&
+ rotation_direction == Ship.CLOCKWISE
+ ||
+ keyCode == keyMapping.left &&
+ rotation_direction == Ship.COUNTERCLOCKWISE) {
+ ship.rotate(Ship.STOP); //stop rotation
+ rotation_direction = Ship.STOP;
+ }
+ }
+
+ public void keyTyped(KeyEvent e) {
+ // have to implement this because it's in KeyListener
+ }
+}
+
+class KeyMapping {
+
+ static final KeyMapping keyMapping1 =
+ new KeyMapping(KeyEvent.VK_LEFT,
+ KeyEvent.VK_RIGHT,
+ KeyEvent.VK_UP,
+ KeyEvent.VK_SPACE);
+
+ static final KeyMapping keyMapping2 =
+ new KeyMapping(KeyEvent.VK_X,
+ KeyEvent.VK_V,
+ KeyEvent.VK_D,
+ KeyEvent.VK_ALT);
+
+ int left, right, thrust, fire;
+
+ KeyMapping(int k_left, int k_right, int k_thrust, int k_fire) {
+ left = k_left;
+ right = k_right;
+ thrust = k_thrust;
+ fire = k_fire;
+ }
+}
diff --git a/docs/dist/examples/spacewar/README.html b/docs/dist/examples/spacewar/README.html
new file mode 100644
index 000000000..8b6a56910
--- /dev/null
+++ b/docs/dist/examples/spacewar/README.html
@@ -0,0 +1,79 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>Space War</title>
+</head>
+
+<body BGCOLOR="white">
+
+<P>&copy; Copyright 1997-2001 Xerox Corporation. All rights
+reserved.</P>
+
+<P><B>Last updated</B>: January 10, 2001</P>
+
+<p>&nbsp;</p>
+
+
+
+<h2><a name="5">Exploring the Spacewar Example</a></h2>
+
+<P>The code in this directory is an implementation of the
+classic video game Spacewar.</P>
+
+<P>The Spacewar game is intended to provide a modest-sized example of
+a program that uses aspects. The code for this example is evolving,
+as we add new features to AspectJ and come up with a better
+understanding of how to use the features.</P>
+
+<P>In order to compile and run this example, make sure to have the latest
+version of AspectJ correctly installed. If you're not sure you do, try the
+helloworld example first by following the instructions in <a href="../doc/primer/default.html">Primer</a>
+section Getting Started.</P>
+
+<h3><a name="5.1">Compiling Spacewar</a></h3>
+
+<ul>
+<li> Change to the <code>examples</code> directory. </li>
+
+<li> Type <code><strong>ajc -argfile spacewar/demo.lst</strong></code> to compile the
+ system.</li>
+</ul>
+
+<h3><a name="5.2">Running Spacewar</a></h3>
+
+<ul>
+<li> In the examples directory, type <code><strong>java spacewar.Game</strong></code></li>
+</ul>
+
+<p>When the game starts up you will see two different displays. These
+are the two built-in display aspects of the game. In each you will
+see a single white ship and two red ships. The white ship is yours
+to control; the red ships are an enemy robots. Your ship is controlled
+with the four arrow keys to turn, thrust and stop; the spacebar
+fires. As you play, the game will be displayed in both windows.</p>
+
+<p>You can quit the game with ctl-Q.</p>
+
+<h3><a name="5.3">Exploring the Code</a></h3>
+
+<p>There is one other built-in configurations for the Spacewar game.
+Try it by typing <code><strong>ajc @spacewar\debug.lst</strong></code>. This
+compiles in an elaborate debugging aspect for the game.
+
+</p>
+
+<p> We recommend you explore the Spacewar source code and look at the
+aspects that it uses. You will find several of them, of different
+scales and different degrees of cross-cutting. Remember that these
+represent our evolving understanding of how to use AspectJ to
+implement Spacewar. If you believe we should be doing something
+differently, then please let us know.
+</p>
+
+
+</body>
+
+</html>
diff --git a/docs/dist/examples/spacewar/Registry.java b/docs/dist/examples/spacewar/Registry.java
new file mode 100644
index 000000000..a9cec0418
--- /dev/null
+++ b/docs/dist/examples/spacewar/Registry.java
@@ -0,0 +1,126 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Registry.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.util.Vector;
+import java.util.Hashtable;
+import java.util.Enumeration;
+
+/**
+ * The Registry keeps track of all the space objects that are floating around.
+ * It basically supports register, unregister and contents type operations.
+ *
+ * The synchronization is done by the RegistrySynchronization aspect.
+ */
+
+class Registry {
+
+ private Hashtable table;
+ private Game game;
+
+ Game getGame() { return game; }
+
+ Registry (Game theGame) {
+ game = theGame;
+ table = new Hashtable();
+ }
+
+
+ void register(SpaceObject object) {
+ table.put(object, object);
+ }
+
+ void unregister(SpaceObject object) {
+ table.remove(object);
+ }
+
+ /*
+ * It is an invariant of the design that only two points in SpaceObject
+ * should call register and unregister. This aspect enforces that.
+ *
+ * Unfortunately, in the current compiler, we get a static warning when
+ * there are no illegal calls that this advice has no targets. That will
+ * be fixed in a future release. For the time being the dummy method
+ * just below this fixes that.
+ */
+ static aspect RegistrationProtection {
+ after() returning():
+ (call(void Registry.register(SpaceObject)) ||
+ call(void Registry.unregister(SpaceObject))) &&
+ !(within(SpaceObject) && (withincode(new(..)) ||
+ withincode(void die()))) {
+ throw new IllegalAccessError(
+ "This is an illegal call to " + thisJoinPoint + "\n" +
+ "Only the constructor and the die() on SpaceObject\n" +
+ "should call the primitive registry operations.");
+ }
+ }
+
+ void dummy() { // see comment above
+ register(getObjects()[0]);
+ unregister(getObjects()[0]);
+ }
+
+
+ SpaceObject[] getObjects() {
+ SpaceObject[] allObjects = new SpaceObject[table.size()];
+ Enumeration elements = table.elements();
+ for(int i = 0; elements.hasMoreElements(); i++) {
+ allObjects[i] = (SpaceObject)(elements.nextElement());
+ }
+ return allObjects;
+ }
+
+ Ship[] getShips() {
+ //
+ // First we have to put just the Ships into a vector, then we can put
+ // them into an array of exactly the right length.
+ //
+ Ship[] arrayOfShips;
+ Vector vectorOfShips = new Vector();
+ Enumeration elements = table.elements();
+ while (elements.hasMoreElements()) {
+ Object object = elements.nextElement();
+ if (object instanceof Ship) {
+ vectorOfShips.addElement(object);
+ }
+ }
+
+ arrayOfShips = new Ship[(vectorOfShips.size())];
+ vectorOfShips.copyInto(arrayOfShips);
+ return arrayOfShips;
+ }
+
+ Hashtable getTable() { return table; }
+
+ //
+ // The protocol for clockTick is that it automatically cascades.
+ //
+ void clockTick() {
+ Enumeration elements = table.elements();
+ while (elements.hasMoreElements()) {
+ ((SpaceObject)elements.nextElement()).clockTick();
+ }
+ }
+}
+
diff --git a/docs/dist/examples/spacewar/RegistrySynchronization.java b/docs/dist/examples/spacewar/RegistrySynchronization.java
new file mode 100644
index 000000000..986e4bd30
--- /dev/null
+++ b/docs/dist/examples/spacewar/RegistrySynchronization.java
@@ -0,0 +1,58 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+RegistrySynchronization.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import coordination.Coordinator;
+
+
+/**
+ * This aspect ensures synchronized access to methods of the Registry in
+ * the presence of several threads.
+ *
+ * It uses the Coordinator class, from the AspectJ coordination library.
+ *
+ * It uses a per-Registry coordination scheme, so there is one instance of
+ * this class for each instance of the Registry class. When this class is
+ * constructed, it registers appropriate mutexes and selfexes using the
+ * behavior inherited from Coordinator.
+ *
+ * The mutating methods (register and unregister) should be self-exclusive.
+ * Each reader method should be mutually exclusive with the mutating
+ * methods. But the readers can run concurrently. */
+aspect RegistrySynchronization extends Coordinator perthis(this(Registry)) {
+
+ protected pointcut synchronizationPoint():
+ call(void Registry.register(..)) ||
+ call(void Registry.unregister(..)) ||
+ call(SpaceObject[] Registry.getObjects(..)) ||
+ call(Ship[] Registry.getShips(..));
+
+ public RegistrySynchronization() {
+ addSelfex("register");
+ addSelfex("unregister");
+
+ addMutex(new String[] {"register", "unregister", "getObjects"});
+ addMutex(new String[] {"register", "unregister", "getShips"});
+ }
+
+}
diff --git a/docs/dist/examples/spacewar/Robot.java b/docs/dist/examples/spacewar/Robot.java
new file mode 100644
index 000000000..05f276108
--- /dev/null
+++ b/docs/dist/examples/spacewar/Robot.java
@@ -0,0 +1,201 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Robot.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.util.Random;
+
+/**
+ * Robot is an automatic pilot that now has quite a bit of intelligence.
+ * So, beware !
+ */
+class Robot extends Pilot implements Runnable {
+
+ private static final int FIRE_INTERVAL = 60;
+ private static final int REBIRTH_DELAY = 900;
+
+ private final Random random = new Random();
+
+ private Thread runner;
+ private boolean runnable = true;
+
+ Robot(Game theGame, int number) {
+ super(theGame, number);
+ }
+
+ void start() {
+ if (runner == null) {
+ runner = new Thread(this);
+ runner.start();
+ }
+ }
+
+ void destroy() {
+ if (runner != null) {
+ runnable = false;
+ runner = null;
+ }
+ }
+
+
+ // A Robot tracks User-controlled ships and fires at them
+ public void run() {
+ Ship target = null;
+
+ while(runnable) {
+ // find target ship
+ do {
+ Ship[] potentials = getGame().getRegistry().getShips();
+ if(potentials.length != 0)
+ target = potentials[Math.abs(random.nextInt() % potentials.length)];
+ sleepForABit(25);
+ } while (target == ship);
+ // main loop
+ int currentRotation = Ship.STOP;
+ int time;
+ boolean currentlyAccelerating = false;
+ double dx, dy, angleA, angleB, theta, dtheta, d,
+ targetVel, a, b, c, targetXVel, targetYVel;
+
+ while(true) {
+ sleepForABit(FIRE_INTERVAL);
+
+ // if my ship is destroyed, give me a new one
+ if (!ship.isAlive()) {
+ sleepForABit(REBIRTH_DELAY);
+ getGame().newShip(this);
+ }
+
+ // find direction and distance from target to me
+ dx = ship.getXPos() - target.getXPos();
+ if (dx < - getGame().getWidth() / 2)
+ dx += getGame().getWidth();
+ if (dx > getGame().getWidth() / 2)
+ dx -= getGame().getWidth();
+ dy = ship.getYPos() - target.getYPos();
+ if (dy < - getGame().getHeight() / 2)
+ dy += getGame().getHeight();
+ if (dy > getGame().getHeight() / 2)
+ dy -= getGame().getHeight();
+ d = Math.sqrt(dx * dx + dy * dy);
+ angleA = Math.atan(dy / dx);
+ if (dx < 0)
+ angleA += Math.PI;
+
+ // find relative velocity and trajectory of target
+ targetXVel = target.getXVel() - ship.getXVel();
+ targetYVel = target.getYVel() - ship.getYVel();
+ targetVel = Math.sqrt(targetXVel * targetXVel +
+ targetYVel * targetYVel);
+ angleB = Math.atan(targetYVel / targetXVel);
+ if (targetXVel < 0)
+ angleB+=Math.PI;
+
+ // find angle between line to target and taget's direction of travel
+ theta = (angleA - angleB) % (2 * Math.PI);
+ if (theta < -Math.PI)
+ theta += 2 * Math.PI;
+ if (theta > Math.PI)
+ theta -= 2 * Math.PI;
+
+ // calculate time to bullet impact using law of cosines
+ a = targetVel * targetVel + Ship.BULLET_SPEED * Ship.BULLET_SPEED;
+ b = d * targetVel * Math.cos(theta);
+ c = - d * d;
+ time = (int)((-b + Math.sqrt(b * b - 4 * a * c)) / 2 / a);
+
+ // calculate angle and distance to bullet impact location
+ dx = targetXVel * time - dx;
+ dy = targetYVel * time - dy;
+ theta = Math.atan(dy / dx);
+ if(dx < 0)
+ theta += Math.PI;
+
+ // find desired change in rotation
+ dtheta = (theta - ship.getOrientation()) % (2 * Math.PI);
+ // find the shortest path to the desired orientation;
+ if(dtheta < - Math.PI)
+ dtheta += 2 * Math.PI;
+ if(dtheta > Math.PI)
+ dtheta -= 2 * Math.PI;
+
+ // turn if nessecary
+ if (dtheta > Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
+ if (currentRotation != Ship.CLOCKWISE)
+ ship.rotate(currentRotation = Ship.CLOCKWISE);
+ }
+ else if (dtheta < -Ship.DEFAULT_ANGULAR_VELOCITY / 2) {
+ if (currentRotation != Ship.COUNTERCLOCKWISE)
+ ship.rotate(currentRotation = Ship.COUNTERCLOCKWISE);
+ } // otherwise, fire, maybe even a burst
+ else {
+ if(currentRotation != Ship.STOP)
+ ship.rotate(currentRotation = Ship.STOP);
+ if (random.nextInt() % 40 == 0) {
+ ship.fire();
+ }
+ }
+
+ // randomly accelerate
+ if (currentlyAccelerating && random.nextInt() % 2 == 0)
+ ship.thrust(currentlyAccelerating = false);
+ else {
+ if (ship.getXVel() == 0)
+ angleA = 0;
+ else
+ angleA = Math.atan(ship.getYVel() / ship.getXVel());
+
+ if (ship.getXVel() < 0)
+ angleA+=Math.PI;
+ angleB = (angleA - ship.getOrientation()) % (2 * Math.PI);
+ if (angleB < -Math.PI)
+ angleB += 2 * Math.PI;
+ if (angleB > Math.PI)
+ angleB -= 2 * Math.PI;
+ angleB = Math.abs(angleB);
+
+ // angleB now represents the angle between the ship's
+ // orientation and velocity vector. This will be used to
+ // determine the probably that the ship will thrust to
+ // prevent ships from accelerating too much in one direction
+ if (random.nextInt() % (int)(12 * (Math.PI - angleB) + 1) == 0)
+ ship.thrust(currentlyAccelerating = true);
+ }
+
+ // switch targets if current one has been destroyed
+ if (target.getDamage() == 100)
+ break;
+
+ // randomly switch targets
+ if (random.nextInt() % 4000 == 0)
+ break;
+ }
+ }
+ }
+
+ void sleepForABit (int time) {
+ try {
+ runner.sleep(time);
+ }
+ catch (InterruptedException e) {}
+ }
+}
diff --git a/docs/dist/examples/spacewar/SWFrame.java b/docs/dist/examples/spacewar/SWFrame.java
new file mode 100644
index 000000000..6dfb9f6f6
--- /dev/null
+++ b/docs/dist/examples/spacewar/SWFrame.java
@@ -0,0 +1,92 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+SWFrame.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+import java.awt.Frame;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.Dimension;
+import java.awt.Insets;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+class SWFrame extends Frame implements ActionListener {
+ private Game game;
+ private Display display;
+ private Menu menu;
+
+ Game getGame() { return game; }
+ Display getDisplay() { return display; }
+ Menu getMenu() { return menu; }
+
+ SWFrame(Game theGame, Display d) {
+ super("Space War!");
+
+ game = theGame;
+
+ display = d;
+ add(display);
+
+ // create menu
+ menu = new Menu("Game");
+ MenuItem item1 = new MenuItem("Add Robot", new MenuShortcut('a'));
+ MenuItem item2 = new MenuItem("Reset Ships", new MenuShortcut('r'));
+ MenuItem item3 = new MenuItem("Quit", new MenuShortcut('q'));
+ item1.setActionCommand("Add Robot");
+ item2.setActionCommand("Reset Ships");
+ item3.setActionCommand("Quit");
+ menu.add(item1);
+ menu.add(item2);
+ menu.add(item3);
+ menu.addActionListener(this);
+
+ setMenuBar(new MenuBar());
+ getMenuBar().add(menu);
+
+ Dimension screenSize = new Dimension(500, 500);
+ setSize(screenSize);
+ setVisible(true);
+ toFront();
+
+ Insets inset = getInsets();
+ int displayWidth = screenSize.width - inset.left - inset.right;
+ int displayHeight = screenSize.height - inset.top - inset.bottom;
+ display.setSize(displayWidth, displayHeight);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ String s = e.getActionCommand();
+ if (s.equals("Add Robot")) {
+ getGame().addRobot();
+ }
+ else if (s.equals("Reset Ships")) {
+ getGame().resetShips();
+ }
+ else if (s.equals("Quit")) {
+ getGame().quit();
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/Ship.java b/docs/dist/examples/spacewar/Ship.java
new file mode 100644
index 000000000..9978fe694
--- /dev/null
+++ b/docs/dist/examples/spacewar/Ship.java
@@ -0,0 +1,296 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+Ship.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+class Ship extends SpaceObject {
+
+ pointcut helmCommandsCut(Ship ship):
+ target(ship) && ( call(void rotate(int)) ||
+ call(void thrust(boolean)) ||
+ call(void fire()) );
+
+
+ /**
+ * Energy and Damage are key values in the state of a ship. Energy is
+ * basically about fuel, and damage is about how bad a shape we are in.
+ *
+ * The energy related values are:
+ * <ul>
+ * <li>MAX_ENERGY</li>
+ * <li>BULLET_ENERGY</li>
+ * <li>ACCELERATION_ENERGY_FACTOR</li>
+ * <li>energy</li>
+ * </ul>
+ * The damage related values are:
+ * <ul>
+ * <li>MAX_DAMAGE</li>
+ * <li>BULLET_DAMAGE</li>
+ * <li>COLLISION_DAMAGE_FACTOR</li>
+ * <li>damage</li>
+ * </ul>
+ * Finally, REPAIR_RATE is the rate at which energy is consumed to fix
+ * damage.
+ *
+ */
+ private static final int MAX_ENERGY = 100;
+ private static final int BULLET_ENERGY= 2;
+ private static final double ACCELERATION_COST_FACTOR = 0.05;
+
+ //XXX was private
+ static final int MAX_DAMAGE = 100;
+ private static final int BULLET_DAMAGE = 15;
+ private static final double COLLISION_DAMAGE_FACTOR = 0.1;
+
+ private static final double REPAIR_RATE = 0.08;
+
+
+ private static final int EXPLOSION_LENGTH = 10;
+
+ static final int BULLET_SPEED = 10;
+
+ static final int CLOCKWISE = 1;
+ static final int STOP = 0;
+ static final int COUNTERCLOCKWISE = (-1);
+
+ static final double DEFAULT_ANGULAR_VELOCITY = 0.2;
+ static final double DEFAULT_ACCELERATION = .4;
+
+ static private final int SIZE = 30; //Can't be changed for now!!!
+
+ private double energy; // range: 0 to MAX_ENERGY
+ private double damage; // range: 0 to MAX_DAMAGE
+ private double orientation; // in degrees
+ private double angularVel; // in ???
+ private double xAcc, yAcc, rAcc; //
+ private int countdown; // remaining explosion time
+
+ private Pilot pilot;
+
+ Ship(Game theGame, double xPos, double yPos, double orientation) {
+ super(theGame, xPos, yPos, 0, 0);
+ xAcc = 0;
+ yAcc = 0;
+ this.orientation = orientation;
+ angularVel = 0;
+
+ energy = MAX_ENERGY;
+ damage = 0;
+ countdown = EXPLOSION_LENGTH;
+ }
+
+
+ int getSize() { return SIZE; }
+
+ double getEnergy() { return energy; }
+ double getDamage() { return damage; }
+ double getOrientation() { return orientation; }
+ double getRAcc() { return rAcc; }
+
+ Pilot getPilot() { return pilot; }
+ void setPilot (Pilot p) { pilot = p; }
+
+ float getEnergyLevel() {
+ return (float)energy / (float)MAX_ENERGY;
+ }
+ float getDamageLevel() {
+ return (float)damage / (float)MAX_DAMAGE;
+ }
+
+ /** returns false if energy is out, otherwise decrements energy by amount
+ * and returns true
+ */
+ boolean expendEnergy(double amount) {
+ if (amount <= energy) {
+ energy -= amount;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /** increments damage by amount and handles the destruction of a ship if
+ * damage reaches MAX_DAMAGE.
+ */
+ void inflictDamage(double amount) {
+ if (amount < 0) // shouldn't happen
+ return;
+ damage = Math.min(MAX_DAMAGE, damage + amount);
+ if (damage == MAX_DAMAGE)
+ setIsAlive(false);
+ }
+
+ /** repairs some damage
+ */
+ void repairDamage(double amount) {
+ if (amount < 0) // shouldn't happen
+ return;
+ if (damage == 0)
+ return;
+ damage = Math.max(0, damage - amount);
+ }
+
+ public void clockTick() {
+ if (! isAlive()) {
+ //
+ // If we aren't alive, but we are still in the registry, it means
+ // we are exploding. countdown counts the length of the explosion.
+ //
+ if (--countdown == 0)
+ die();
+ }
+ else {
+ if (angularVel != 0) {
+ orientation += angularVel;
+ xAcc = rAcc * Math.cos(orientation);
+ yAcc = rAcc * Math.sin(orientation);
+ }
+ setXVel(getXVel() + xAcc);
+ setYVel(getYVel() + yAcc);
+
+ //expend energy
+ if (!expendEnergy(rAcc * ACCELERATION_COST_FACTOR))
+ rAcc = xAcc = yAcc = 0;
+
+ // fix damage
+ if (energy > 10 && damage > REPAIR_RATE) {
+ expendEnergy(REPAIR_RATE);
+ repairDamage(REPAIR_RATE);
+ }
+ }
+ super.clockTick();
+ }
+
+ /**
+ * First check to make sure we have enough energy to accelerate. If
+ * we do, then go ahead and do so. Acceleration is in the direction
+ * we are already facing (i.e. orientation).
+ */
+ void setAcceleration(double acc) {
+ if (acc * ACCELERATION_COST_FACTOR <= energy) {
+ rAcc = acc;
+ xAcc = rAcc * Math.cos(orientation);
+ yAcc = rAcc * Math.sin(orientation);
+ }
+ }
+
+ /**
+ * First check to make sure we have enough energy to rotate. If
+ * we do, then go ahead and do so.
+ */
+ void setAngularVelocity(double omega) {
+ // changing direction of rotation takes energy
+ if (!expendEnergy(Math.abs(omega - angularVel) / 2))
+ return;
+ //sets amount of degree rotation per clock tick, in radians;
+ //clockwise is positive
+ angularVel = omega;
+ }
+
+ /** affect rotation thrusters. Direction can be one of {@link
+ * #CLOCKWISE}, {@link #COUNTERCLOCKWISE}, or zero for turning off
+ * the thrusters.
+ */
+ void rotate(int direction) {
+ setAngularVelocity(
+ direction == CLOCKWISE ? DEFAULT_ANGULAR_VELOCITY :
+ direction == COUNTERCLOCKWISE ? -DEFAULT_ANGULAR_VELOCITY :
+ 0);
+ }
+
+ /** turn on acceleration */
+ void thrust(boolean onOff) {
+ setAcceleration(onOff ? DEFAULT_ACCELERATION : 0);
+ }
+
+ /** create a bullet and fire it */
+ void fire() {
+ // firing a shot takes energy
+ if (!expendEnergy(BULLET_ENERGY))
+ return;
+
+ //create a bullet object so it doesn't hit the ship that's firing it
+ double xV = getXVel() + BULLET_SPEED * (Math.cos(orientation));
+ double yV = getYVel() + BULLET_SPEED * (Math.sin(orientation));
+
+ // create the actual bullet
+ new Bullet(
+ getGame(),
+ (getXPos() + ((getSize()/2 + 2) * (Math.cos(orientation))) + xV),
+ (getYPos() + ((getSize()/2 + 2) * (Math.sin(orientation))) + yV),
+ xV,
+ yV);
+ }
+
+
+ void handleCollision(SpaceObject obj) {
+ if (obj instanceof Ship) {
+ // should never be called. ship - ship collisions are handled in
+ // Ship.bounce(Ship shipA, Ship shipB)
+ }
+ else if (obj instanceof Bullet) {
+ inflictDamage(BULLET_DAMAGE);
+ }
+ else if (obj instanceof EnergyPacket) {
+ double packetEnergy = ((EnergyPacket)obj).getEnergy();
+ energy = Math.max(0, Math.min(energy + packetEnergy, MAX_ENERGY));
+ }
+ else {
+ System.err.println("collision with UFO!");
+ }
+ }
+
+ static void bounce(Ship shipA, Ship shipB) {
+ double dx, dy, denominator,
+ xAccA, yAccA, xAccB, yAccB, damage,
+ xComp, yComp, dvx, dvy;
+
+ dx = Math.abs(shipA.getXPos() - shipB.getXPos());
+ dy = Math.abs(shipA.getYPos() - shipB.getYPos());
+ denominator = Math.sqrt(dx * dx + dy * dy);
+ xComp = dx / denominator;
+ yComp = dy / denominator;
+ xAccA = shipB.getXVel() * xComp + shipA.getXVel() * (1 - xComp) -
+ shipA.getXVel();
+ yAccA = shipB.getYVel() * yComp + shipA.getYVel() * (1 - yComp) -
+ shipA.getYVel();
+ xAccB = shipA.getXVel() * xComp + shipB.getXVel() * (1 - xComp) -
+ shipB.getXVel();
+ yAccB = shipA.getYVel() * yComp + shipB.getYVel() * (1 - yComp) -
+ shipB.getYVel();
+ shipA.accelerate(xAccA, yAccA);
+ shipB.accelerate(xAccB, yAccB);
+ dvx = shipA.getXVel() - shipB.getXVel();
+ dvy = shipA.getYVel() - shipA.getYVel();
+ damage = COLLISION_DAMAGE_FACTOR * (dvx * dvx + dvy * dvy);
+ shipA.inflictDamage(damage);
+ shipB.inflictDamage(damage);
+
+ // !!!
+ // !!! poopers! this does a local time warp. this has to be a
+ // !!! violation of the clockTick protocol
+ // !!!
+ while (Game.isCollision(shipA, shipB)) {
+ shipA.clockTick();
+ shipB.clockTick();
+ }
+ }
+}
diff --git a/docs/dist/examples/spacewar/SpaceObject.java b/docs/dist/examples/spacewar/SpaceObject.java
new file mode 100644
index 000000000..ee3afabcc
--- /dev/null
+++ b/docs/dist/examples/spacewar/SpaceObject.java
@@ -0,0 +1,106 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+SpaceObject.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+/**
+ * SpaceObjects are objects that float around in space. They support the
+ * minimal SpaceObject protocol, having to do with position, velocity,
+ * size and liveness. They are constructed with game, position, velocity
+ * and size. When constructed, a spaceobject adds itself to the registry.
+ *
+ * When it dies, a spaceobject removes itself from the registry. But note
+ * that it doesn't decide when to die, subclasses do that.
+ *
+ * The display aspects actually draw the space object on the screen and say
+ * how much space it takes up there.
+ */
+abstract class SpaceObject {
+
+ private Game game;
+ private double xPos, yPos, oldXPos, oldYPos, xVel, yVel;
+ private boolean alive;
+
+ SpaceObject (Game theGame, double xP, double yP, double xV, double yV) {
+ game = theGame;
+ xPos = xP;
+ yPos = yP;
+ oldXPos = xP;
+ oldYPos = yP;
+ xVel = xV;
+ yVel = yV;
+
+ alive = true;
+ getGame().getRegistry().register(this);
+ }
+
+ Game getGame() { return game; }
+
+ double getXPos() { return xPos; }
+ double getYPos() { return yPos; }
+
+ double getOldXPos() { return oldXPos; }
+ double getOldYPos() { return oldYPos; }
+
+ double getXVel() { return xVel; }
+ double getYVel() { return yVel; }
+
+ void setXVel (double n) { xVel = n; }
+ void setYVel (double n) { yVel = n; }
+
+ boolean isAlive() { return alive; }
+ void setIsAlive(boolean n) { alive = n; }
+
+
+ /**
+ * Move 1 unit of time's worth of distance. I.e. increment xPos by xVel
+ * and yPos by yVel. If we move off an edge of the screen move us back
+ * in the opposite edge.
+ */
+ void clockTick() {
+ oldXPos = xPos;
+ oldYPos = yPos;
+ xPos = (xPos + xVel) % getGame().getWidth();
+ if(xPos < 0)
+ xPos += getGame().getWidth();
+ yPos = (yPos + yVel) % getGame().getHeight();
+ if(yPos < 0)
+ yPos += getGame().getHeight();
+ }
+
+ void accelerate(double dXVel, double dYVel) {
+ xVel += dXVel;
+ yVel += dYVel;
+ }
+
+ void die() {
+ getGame().getRegistry().unregister(this);
+ }
+
+ abstract int getSize();
+
+ /** resolve the effects of colliding with a space object.
+ * @param obj the space object that this object is colliding with.
+ */
+ abstract void handleCollision(SpaceObject obj);
+}
diff --git a/docs/dist/examples/spacewar/Timer.java b/docs/dist/examples/spacewar/Timer.java
new file mode 100644
index 000000000..1f4a992a7
--- /dev/null
+++ b/docs/dist/examples/spacewar/Timer.java
@@ -0,0 +1,53 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+
+Timer.java
+Part of the Spacewar system.
+
+*/
+
+package spacewar;
+
+
+class Timer extends Thread {
+
+ private final static int TICK_PERIOD = 40; // time between ticks in millis
+
+ private Game game;
+
+ Game getGame() { return game; }
+
+ Timer (Game theGame) {
+ super("Timer");
+ game = theGame;
+ }
+
+ public void run() {
+ long t1, tdiff;
+ while (true) {
+ t1 = System.currentTimeMillis();
+ getGame().clockTick();
+ tdiff = System.currentTimeMillis() - t1;
+ if (tdiff < TICK_PERIOD) {
+ try {
+ sleep (Math.max(0 , TICK_PERIOD - tdiff));
+ }
+ catch (InterruptedException e) { }
+ }
+ }
+ }
+}
diff --git a/docs/dist/examples/telecom/AbstractSimulation.java b/docs/dist/examples/telecom/AbstractSimulation.java
new file mode 100644
index 000000000..1c44af7a7
--- /dev/null
+++ b/docs/dist/examples/telecom/AbstractSimulation.java
@@ -0,0 +1,80 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public abstract class AbstractSimulation {
+
+ public static AbstractSimulation simulation;
+
+ /**
+ * Creates objects and puts them to work.
+ */
+ public void run() {
+ Customer jim = new Customer("Jim", 650);
+ Customer mik = new Customer("Mik", 650);
+ Customer crista = new Customer("Crista", 415);
+
+ say("jim calls mik...");
+ Call c1 = jim.call(mik);
+ wait(1.0);
+ say("mik accepts...");
+ mik.pickup(c1);
+ wait(2.0);
+ say("jim hangs up...");
+ jim.hangup(c1);
+ report(jim);
+ report(mik);
+ report(crista);
+
+ say("mik calls crista...");
+ Call c2 = mik.call(crista);
+ say("crista accepts...");
+ crista.pickup(c2);
+ wait(1.5);
+ say("crista hangs up...");
+ crista.hangup(c2);
+ report(jim);
+ report(mik);
+ report(crista);
+ }
+
+ /**
+ * Print a report of the connection time for customer
+ */
+ abstract protected void report(Customer c);
+
+ /**
+ * Wait 0.1 seconds per "second" for simulation
+ */
+ protected static void wait(double seconds) {
+ Object dummy = new Object();
+ synchronized (dummy) {
+ //XXX cheat and only wait 0.1 seconds per second
+ try {dummy.wait((long)(seconds*100)); }
+ catch (Exception e) {}
+ }
+ }
+
+ /**
+ * Put a message on standard output
+ */
+ protected static void say(String s){
+ System.out.println(s);
+ }
+
+}
diff --git a/docs/dist/examples/telecom/BasicSimulation.java b/docs/dist/examples/telecom/BasicSimulation.java
new file mode 100644
index 000000000..ab7426376
--- /dev/null
+++ b/docs/dist/examples/telecom/BasicSimulation.java
@@ -0,0 +1,34 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.run(..)
+ * with a test script for the telecom system with only the
+ * basic objects.
+ */
+public class BasicSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ simulation = new BasicSimulation();
+ simulation.run();
+ }
+
+ protected void report(Customer c) { }
+
+}
diff --git a/docs/dist/examples/telecom/Billing.java b/docs/dist/examples/telecom/Billing.java
new file mode 100644
index 000000000..c69ca758c
--- /dev/null
+++ b/docs/dist/examples/telecom/Billing.java
@@ -0,0 +1,80 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package telecom;
+/**
+ * The Billing aspect deals with... billing.
+ * How much money did each connection cost?
+ * How much money did each call cost?
+ * How much money is being debited to a customer?
+ * This aspect can be used by other parts of the system. (not in this example)
+ *
+ * Billing can depend many things, such as timing, the type of the connection,
+ * some special discounts the customer has, special features, etc. In here,
+ * it depends only on timing and on the type of the connection.
+ */
+public aspect Billing {
+ // domination required to get advice on endtiming in the right order
+ declare dominates: Billing, Timing;
+
+ 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; }
+ /**
+ * Caller pays for the call
+ */
+ after(Customer cust) returning (Connection conn):
+ args(cust, ..) && call(Connection+.new(..)) {
+ conn.payer = cust;
+ }
+
+ /**
+ * Connections give the appropriate call rate
+ */
+ public abstract long Connection.callRate();
+
+
+ public long LongDistance.callRate() { return LONG_DISTANCE_RATE; }
+ public long Local.callRate() { return LOCAL_RATE; }
+
+
+ /**
+ * When timing stops, calculate and add the charge from the
+ * connection time
+ */
+ 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);
+ }
+
+
+ /**
+ * Customers have a bill paying aspect with state
+ */
+ public long Customer.totalCharge = 0;
+ public long getTotalCharge(Customer cust) { return cust.totalCharge; }
+
+ public void Customer.addCharge(long charge){
+ totalCharge += charge;
+ }
+}
diff --git a/docs/dist/examples/telecom/BillingSimulation.java b/docs/dist/examples/telecom/BillingSimulation.java
new file mode 100644
index 000000000..09f273ff6
--- /dev/null
+++ b/docs/dist/examples/telecom/BillingSimulation.java
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.report(..)
+ *
+ */
+public class BillingSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ System.out.println("\n... Billing simulation 2 ...\n");
+ simulation = new BillingSimulation();
+ simulation.run();
+ }
+
+ /**
+ * Print a report of the connection time and the bill for customer
+ */
+ protected void report(Customer c){
+ Timing t = Timing.aspectOf();
+ Billing b = Billing.aspectOf();
+ System.out.println(c + " has been connected for "
+ + t.getTotalConnectTime(c)
+ + " seconds and has a bill of "
+ + b.getTotalCharge(c));
+ }
+}
+
diff --git a/docs/dist/examples/telecom/Call.java b/docs/dist/examples/telecom/Call.java
new file mode 100644
index 000000000..738d2d348
--- /dev/null
+++ b/docs/dist/examples/telecom/Call.java
@@ -0,0 +1,97 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+import java.util.Vector;
+import java.util.Enumeration;
+
+/**
+ * A call supports the process of a customer trying to
+ * connect to others.
+ */
+public class Call {
+
+ private Customer caller, receiver;
+ private Vector connections = new Vector();
+
+ /**
+ * Create a new call connecting caller to receiver
+ * with a new connection. This should really only be
+ * called by Customer.call(..)
+ */
+ public Call(Customer caller, Customer receiver) {
+ this.caller = caller;
+ this.receiver = receiver;
+ Connection c;
+ if (receiver.localTo(caller)) {
+ c = new Local(caller, receiver);
+ } else {
+ c = new LongDistance(caller, receiver);
+ }
+ connections.add(c);
+ }
+
+ /**
+ * picking up a call completes the current connection
+ * (this means that you shouldnt merge calls until
+ * they are completed)
+ */
+ public void pickup() {
+ Connection connection = (Connection)connections.lastElement();
+ connection.complete();
+ }
+
+
+ /**
+ * Is the call in a connected state?
+ */
+ public boolean isConnected(){
+ return ((Connection)connections.lastElement()).getState()
+ == Connection.COMPLETE;
+ }
+
+ /**
+ * hanging up a call drops the connection
+ */
+ public void hangup(Customer c) {
+ for(Enumeration e = connections.elements(); e.hasMoreElements();) {
+ ((Connection)e.nextElement()).drop();
+ }
+ }
+
+ /**
+ * is Customer c one of the customers in this call?
+ */
+ public boolean includes(Customer c){
+ boolean result = false;
+ for(Enumeration e = connections.elements(); e.hasMoreElements();) {
+ result = result || ((Connection)e.nextElement()).connects(c);
+ }
+ return result;
+ }
+
+ /**
+ * Merge all connections from call 'other' into 'this'
+ */
+ public void merge(Call other){
+ for(Enumeration e = other.connections.elements(); e.hasMoreElements();){
+ Connection conn = (Connection)e.nextElement();
+ other.connections.remove(conn);
+ connections.addElement(conn);
+ }
+ }
+}
diff --git a/docs/dist/examples/telecom/Connection.java b/docs/dist/examples/telecom/Connection.java
new file mode 100644
index 000000000..7d54ec843
--- /dev/null
+++ b/docs/dist/examples/telecom/Connection.java
@@ -0,0 +1,87 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * Connections are circuits between customers
+ * There are two kinds: local and long distance
+ * see subclasses at the end of this file.
+ */
+public 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;
+
+ /**
+ * Creatte a new Connection between a and b
+ */
+ Connection(Customer a, Customer b) {
+ this.caller = a;
+ this.receiver = b;
+ }
+
+ /**
+ * what is the state of the connection?
+ */
+ public int getState(){
+ return state;
+ }
+
+ /**
+ * get the customer who initiated this connection
+ */
+ public Customer getCaller() { return caller; }
+
+ /**
+ * get the customer who received this connection
+ */
+ public Customer getReceiver() { return receiver; }
+
+ /**
+ * Called when a call is picked up. This means the b side has picked up
+ * and the connection should now complete itself and start passing data.
+ */
+ void complete() {
+ state = COMPLETE;
+ System.out.println("connection completed");
+ }
+
+ /**
+ * Called when the connection is dropped from a call. Is intended to
+ * free up any resources the connection was consuming.
+ */
+ void drop() {
+ state = DROPPED;
+ System.out.println("connection dropped");
+ }
+
+ /**
+ * Is customer c connected by this connection?
+ */
+ public boolean connects(Customer c){
+ return (caller == c || receiver == c);
+ }
+
+}
+
+
+
diff --git a/docs/dist/examples/telecom/Customer.java b/docs/dist/examples/telecom/Customer.java
new file mode 100644
index 000000000..1e099984c
--- /dev/null
+++ b/docs/dist/examples/telecom/Customer.java
@@ -0,0 +1,112 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+import java.util.Vector;
+
+/**
+ * Customers have a unique id (name in this case for didactic purposes
+ * but it could be telephone number) and area code.
+ * They also have protocol for managing calls: call, pickup, etc.
+ */
+public class Customer {
+
+ private String name;
+ private int areacode;
+ private Vector calls = new Vector();
+
+ /**
+ * unregister a call
+ */
+ protected void removeCall(Call c){
+ calls.removeElement(c);
+ }
+
+ /**
+ * register a call
+ */
+ protected void addCall(Call c){
+ calls.addElement(c);
+ }
+
+ /**
+ * Make a new customer with given name
+ */
+ public Customer(String name, int areacode) {
+ this.name = name;
+ this.areacode = areacode;
+ }
+
+ /**
+ * String rendition of customer
+ */
+ public String toString() {
+ return name + "(" + areacode + ")";
+ }
+
+ /**
+ * what area is the customer in?
+ */
+ public int getAreacode(){
+ return areacode;
+ }
+
+ /**
+ * Is the other customer in the same area?
+ */
+ public boolean localTo(Customer other){
+ return areacode == other.areacode;
+ }
+
+ /**
+ * Make a new call to receiver
+ */
+ public Call call(Customer receiver) {
+ Call call = new Call(this, receiver);
+ addCall(call);
+ return call;
+ }
+
+ /**
+ * pick up a call
+ */
+ public void pickup(Call call) {
+ call.pickup();
+ addCall(call);
+ }
+
+ /**
+ * hang up a call
+ */
+ public void hangup(Call call) {
+ call.hangup(this);
+ removeCall(call);
+ }
+
+ /**
+ * Merge a pair of calls -- conference them
+ * PRE: call1.includes(this)
+ * call2.includes(this)
+ * call1.connected()
+ * call2.connected()
+ * POST: call1 includes all customers connected by call1@pre and call2@pre
+ */
+ public void merge(Call call1, Call call2){
+ call1.merge(call2);
+ removeCall(call2);
+ }
+}
diff --git a/docs/dist/examples/telecom/Local.java b/docs/dist/examples/telecom/Local.java
new file mode 100644
index 000000000..e0bc02679
--- /dev/null
+++ b/docs/dist/examples/telecom/Local.java
@@ -0,0 +1,26 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public class Local extends Connection {
+ Local(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new local connection from " +
+ a + " to " + b + "]");
+ }
+}
diff --git a/docs/dist/examples/telecom/LongDistance.java b/docs/dist/examples/telecom/LongDistance.java
new file mode 100644
index 000000000..b2ed6eb7d
--- /dev/null
+++ b/docs/dist/examples/telecom/LongDistance.java
@@ -0,0 +1,26 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+public class LongDistance extends Connection {
+ LongDistance(Customer a, Customer b) {
+ super(a, b);
+ System.out.println("[new long distance connection from " +
+ a + " to " + b + "]");
+ }
+}
diff --git a/docs/dist/examples/telecom/Timer.java b/docs/dist/examples/telecom/Timer.java
new file mode 100644
index 000000000..813ae3a0d
--- /dev/null
+++ b/docs/dist/examples/telecom/Timer.java
@@ -0,0 +1,50 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+
+/**
+ * Simple timer machine used to record elapsed time
+ */
+public class Timer {
+ public long startTime, stopTime;
+
+ /**
+ * set the start time
+ */
+ public void start() {
+ startTime = System.currentTimeMillis();
+ stopTime = startTime;
+ }
+
+ /**
+ * set the end time
+ */
+ public void stop() {
+ stopTime = System.currentTimeMillis();
+ }
+
+ /**
+ * set how much time passed between last start and stop?
+ */
+ public long getTime() {
+ return stopTime - startTime;
+ }
+}
+
+
diff --git a/docs/dist/examples/telecom/TimerLog.java b/docs/dist/examples/telecom/TimerLog.java
new file mode 100644
index 000000000..4591894dc
--- /dev/null
+++ b/docs/dist/examples/telecom/TimerLog.java
@@ -0,0 +1,29 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+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);
+ }
+}
diff --git a/docs/dist/examples/telecom/Timing.java b/docs/dist/examples/telecom/Timing.java
new file mode 100644
index 000000000..f40bd0fca
--- /dev/null
+++ b/docs/dist/examples/telecom/Timing.java
@@ -0,0 +1,62 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * The Timing aspect is concerned with the duration
+ * of connections and with customer's cumulative
+ * connection time.
+ */
+public aspect Timing {
+
+ /**
+ * Every Customer has a total connection time
+ */
+ public long Customer.totalConnectTime = 0;
+
+ public long getTotalConnectTime(Customer cust) {
+ return cust.totalConnectTime;
+ }
+ /**
+ * Every connection has a timer
+ */
+ private Timer Connection.timer = new Timer();
+ public Timer getTimer(Connection conn) { return conn.timer; }
+
+ /**
+ * Start the timer when call completed
+ */
+ after (Connection c): target(c) && call(void Connection.complete()) {
+ getTimer(c).start();
+ }
+
+ /**
+ * When to stop the timer
+ */
+ pointcut endTiming(Connection c): target(c) &&
+ call(void Connection.drop());
+
+ /**
+ * Stop the timer when call dropped and update the involved parties
+ */
+ after(Connection c): endTiming(c) {
+ getTimer(c).stop();
+ c.getCaller().totalConnectTime += getTimer(c).getTime();
+ c.getReceiver().totalConnectTime += getTimer(c).getTime();
+ }
+}
diff --git a/docs/dist/examples/telecom/TimingSimulation.java b/docs/dist/examples/telecom/TimingSimulation.java
new file mode 100644
index 000000000..309563769
--- /dev/null
+++ b/docs/dist/examples/telecom/TimingSimulation.java
@@ -0,0 +1,40 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+package telecom;
+
+/**
+ * This simulation subclass implements AbstractSimulation.report(..)
+ *
+ */
+public class TimingSimulation extends AbstractSimulation {
+
+ public static void main(String[] args){
+ System.out.println("\n... Timing simulation 2 ...\n");
+ simulation = new TimingSimulation();
+ simulation.run();
+ }
+
+ /**
+ * Print a report of the connection time for customer
+ */
+ protected void report(Customer c){
+ Timing t = Timing.aspectOf();
+ System.out.println(c + " spent " + t.getTotalConnectTime(c));
+ }
+
+}
diff --git a/docs/dist/examples/tjp/Demo.java b/docs/dist/examples/tjp/Demo.java
new file mode 100644
index 000000000..8b90a7a49
--- /dev/null
+++ b/docs/dist/examples/tjp/Demo.java
@@ -0,0 +1,40 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+*/
+package tjp;
+
+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 + ")";
+ }
+
+}
diff --git a/docs/dist/examples/tjp/GetInfo.java b/docs/dist/examples/tjp/GetInfo.java
new file mode 100644
index 000000000..63f13c74e
--- /dev/null
+++ b/docs/dist/examples/tjp/GetInfo.java
@@ -0,0 +1,49 @@
+/*
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+*/
+
+package tjp;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.reflect.CodeSignature;
+
+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]);
+ }
+ }
+}
diff --git a/docs/dist/examples/tracing/Circle.java b/docs/dist/examples/tracing/Circle.java
new file mode 100644
index 000000000..76b73e20a
--- /dev/null
+++ b/docs/dist/examples/tracing/Circle.java
@@ -0,0 +1,71 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * Circle is a 2D shape. It extends the TwoDShape class with the radius
+ * variable, and it implements TwoDShape's abstract methods for
+ * correctly computing a circle's area and distance.
+ *
+ */
+public class Circle extends TwoDShape {
+ protected double r; // radius
+
+ /*
+ * All sorts of constructors
+ */
+ 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);
+ }
+
+ /**
+ * Returns the perimeter of this circle
+ */
+ public double perimeter() {
+ return 2 * Math.PI * r;
+ }
+
+ /**
+ * Returns the area of this circle
+ */
+ public double area() {
+ return Math.PI * r*r;
+ }
+
+ /**
+ * This method overrides the one in the superclass. It adds some
+ * circle-specific information.
+ */
+ public String toString() {
+ return ("Circle radius = " + String.valueOf(r) + super.toString());
+ }
+}
diff --git a/docs/dist/examples/tracing/ExampleMain.java b/docs/dist/examples/tracing/ExampleMain.java
new file mode 100644
index 000000000..93cc465b7
--- /dev/null
+++ b/docs/dist/examples/tracing/ExampleMain.java
@@ -0,0 +1,44 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * A main function for testing 2D shapes.
+ *
+ */
+public class ExampleMain {
+ public static void main(String[] args) {
+ Circle c1 = new Circle(3.0, 3.0, 2.0);
+ Circle c2 = new Circle(4.0);
+
+ Square s1 = new Square(1.0, 2.0);
+
+ System.out.println("c1.perimeter() = " + c1.perimeter());
+ System.out.println("c1.area() = " + c1.area());
+
+ System.out.println("s1.perimeter() = " + s1.perimeter());
+ System.out.println("s1.area() = " + s1.area());
+
+ System.out.println("c2.distance(c1) = " + c2.distance(c1));
+ System.out.println("s1.distance(c1) = " + s1.distance(c1));
+
+ System.out.println("s1.toString(): " + s1.toString());
+ }
+}
diff --git a/docs/dist/examples/tracing/README b/docs/dist/examples/tracing/README
new file mode 100644
index 000000000..6bf89328b
--- /dev/null
+++ b/docs/dist/examples/tracing/README
@@ -0,0 +1,32 @@
+
+This directory contains several examples of tracing aspects,
+including a reusable tracing library and examples of
+using that library.
+
+A lesson in the AspectJ Primer explains all of this code.
+
+To work with these (or any other examples), first be sure .../examples
+is on your classpath, where ... is where you have installed AspectJ.
+
+
+--To compile and run the example without tracing--
+
+ ajc @.../examples/tracing/notrace.lst
+
+ java tracing.ExampleMain
+
+
+--To compile and run the example with tracing version<N>--
+
+ ajc @.../examples/tracing/tracev<N>.lst
+
+ java tracing.version<N>.TraceMyClasses
+
+where <N> is 1, 2, 3 or 4
+
+--To use the tracing.lib.AbstractTrace aspect--
+
+ Make sure .../examples is in your classpath.
+
+ In order to use this aspect, please read the documentation under
+ tracing/doc
diff --git a/docs/dist/examples/tracing/Square.java b/docs/dist/examples/tracing/Square.java
new file mode 100644
index 000000000..78b36882d
--- /dev/null
+++ b/docs/dist/examples/tracing/Square.java
@@ -0,0 +1,71 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing;
+
+/**
+ *
+ * Square is a 2D shape. It extends the TwoDShape class with the side
+ * variable, and it implements TwoDShape's abstract methods for
+ * correctly computing a square's area and distance.
+ *
+ */
+public class Square extends TwoDShape {
+ protected double s; // side
+
+ /*
+ * All sorts of constructors
+ */
+ 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);
+ }
+
+ /**
+ * Returns the perimeter of this square
+ */
+ public double perimeter() {
+ return 4 * s;
+ }
+
+ /**
+ * Returns the area of this square
+ */
+ public double area() {
+ return s*s;
+ }
+
+ /**
+ * This method overrides the one in the superclass. It adds some
+ * circle-specific information.
+ */
+ public String toString() {
+ return ("Square side = " + String.valueOf(s) + super.toString());
+ }
+}
diff --git a/docs/dist/examples/tracing/TwoDShape.java b/docs/dist/examples/tracing/TwoDShape.java
new file mode 100644
index 000000000..960a01b89
--- /dev/null
+++ b/docs/dist/examples/tracing/TwoDShape.java
@@ -0,0 +1,78 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+
+package tracing;
+
+/**
+ *
+ * TwoDShape is an abstract class that defines generic functionality
+ * for 2D shapes.
+ *
+ */
+public abstract class TwoDShape {
+ /**
+ * Coordinates of the center of the shape.
+ */
+ protected double x, y;
+
+ protected TwoDShape(double x, double y) {
+ this.x = x; this.y = y;
+ }
+
+ /**
+ * Returns the x coordinate of the shape.
+ */
+ public double getX() { return x; }
+
+ /**
+ * Returns the y coordinate of the shape.
+ */
+ public double getY() { return y; }
+
+ /**
+ * Returns the distance between this shape and the shape given as
+ * parameter.
+ */
+ 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);
+ }
+
+ /**
+ * Returns the perimeter of this shape. Must be defined in
+ * subclasses.
+ */
+ public abstract double perimeter();
+
+ /**
+ * Returns the area of this shape. Must be defined in
+ * subclasses.
+ */
+ public abstract double area();
+
+ /**
+ * Returns a string representation of 2D shapes -- simply its
+ * coordinates.
+ */
+ public String toString() {
+ return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");
+ }
+}
+
diff --git a/docs/dist/examples/tracing/lib/AbstractTrace.java b/docs/dist/examples/tracing/lib/AbstractTrace.java
new file mode 100644
index 000000000..8c67b12c3
--- /dev/null
+++ b/docs/dist/examples/tracing/lib/AbstractTrace.java
@@ -0,0 +1,185 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.lib;
+
+import java.io.PrintStream;
+import org.aspectj.lang.JoinPoint;
+
+
+/**
+ * This class provides support for printing trace messages into a stream.
+ * The trace messages consist of the class name, method name (if method)
+ * and the list of parameter types.<P>
+ * The class is thread-safe. Different threads may use different output streams
+ * by simply calling the method initStream(myStream).<P>
+ * This class should be extended.
+ * It defines 3 abstract crosscuts for injecting the tracing functionality
+ * into any constructors and methods of any application classes.<P>
+ *
+ * One example of using this class might be
+ * <PRE>
+ * import tracing.lib.AbstractTrace;
+ * aspect TraceMyClasses extends AbstractTrace of eachJVM() {
+ * pointcut classes(): within(TwoDShape) | within(Circle) | within(Square);
+ * pointcut constructors(): executions(new(..));
+ * pointcut methods(): executions(!abstract * *(..))
+ * }
+ * </PRE>
+ * (Make sure .../aspectj/examples is in your classpath)
+ */
+public abstract aspect AbstractTrace {
+
+ /**
+ * Application classes - left unspecified.
+ * Subclasses should concretize this crosscut with class names.
+ */
+ abstract pointcut classes();
+ /**
+ * Constructors - left unspecified.
+ * Subclasses should concretize this crosscut with constructors.
+ */
+ abstract pointcut constructors();
+ /**
+ * Methods - left unspecified.
+ * Subclasses should concretize this crosscut with method names.
+ */
+ abstract pointcut methods();
+
+ before(): classes() && constructors() {
+ doTraceEntry(thisJoinPoint, true);
+ }
+ after(): classes() && constructors() {
+ doTraceExit(thisJoinPoint, true);
+ }
+
+ before(): classes() && methods() {
+ doTraceEntry(thisJoinPoint, false);
+ }
+ after(): classes() && methods() {
+ doTraceExit(thisJoinPoint, false);
+ }
+
+ /*
+ * From here on, it's an ordinary class implementation.
+ * The static state is thread-safe by using ThreadLocal variables.
+ */
+
+ /**
+ * This method initializes this thread's trace output stream.
+ * By default, the output stream is System.err, and it is the same for
+ * all threads. In multithreaded applications, you may want to define
+ * different output streams for the different threads. For doing it,
+ * simply call this method in the beginning of each thread's main loop,
+ * giving it different output streams.
+ */
+ public void initStream(PrintStream _stream) {
+ setStream(_stream);
+ }
+
+
+ private ThreadLocal stream = new ThreadLocal() {
+ protected Object initialValue() {
+ return System.err;
+ }
+ };
+ private ThreadLocal callDepth = new ThreadLocal() {
+ protected Object initialValue() {
+ return new Integer(0);
+ }
+ };
+
+ private PrintStream getStream() {
+ return (PrintStream)stream.get();
+ }
+ private void setStream(PrintStream s) {
+ stream.set(s);
+ }
+ private int getCallDepth() {
+ return ((Integer)(callDepth.get())).intValue();
+ }
+ private void setCallDepth(int n) {
+ callDepth.set(new Integer(n));
+ }
+
+ private void doTraceEntry (JoinPoint jp, boolean isConstructor) {
+ setCallDepth(getCallDepth() + 1);
+ printEntering(jp, isConstructor);
+ }
+
+ private void doTraceExit (JoinPoint jp, boolean isConstructor) {
+ printExiting(jp, isConstructor);
+ setCallDepth(getCallDepth() - 1);
+ }
+
+ private void printEntering (JoinPoint jp, boolean isConstructor) {
+ printIndent();
+ getStream().print("--> ");
+ getStream().print(jp);
+ // printParameterTypes(jp);
+ getStream().println();
+ }
+
+ private void printExiting (JoinPoint jp, boolean isConstructor) {
+ printIndent();
+ getStream().print("<-- ");
+ getStream().print(jp);
+ // printParameterTypes(jp);
+ getStream().println();
+ }
+
+// private void printParameterTypes(JoinPoint jp) {
+// Class[] ptypes = jp.parameterTypes;
+
+// getStream().print("(");
+// for (int i = 0; i < ptypes.length; i++) {
+// getStream().print(ptypes[i].getName());
+// if (i < ptypes.length - 1) getStream().print(", ");
+// }
+// getStream().print(")");
+// }
+
+ private void printIndent() {
+ for (int i = 0; i < getCallDepth(); i++)
+ getStream().print(" ");
+ }
+
+ /**
+ * This method is not being used.
+ * It's being included solely for illustrating how to access and use
+ * the information in JoinPoint.
+ * If you want, you can replace the calls to printParameterTypes (above)
+ * by calls to this method.
+ */
+// private void printParameters(JoinPoint jp) {
+// Class[] ptypes = jp.parameterTypes;
+// String[] pnames = jp.parameterNames;
+// Object[] params = jp.parameters;
+
+// getStream().print("(");
+// for (int i = 0; i < ptypes.length; i++) {
+// getStream().print(ptypes[i].getName() + " " +
+// pnames[i] + "=" +
+// params[i]);
+// if (i < ptypes.length - 1) getStream().print(", ");
+// }
+// getStream().print(")");
+// }
+
+}
+
diff --git a/docs/dist/examples/tracing/lib/TraceMyClasses.java b/docs/dist/examples/tracing/lib/TraceMyClasses.java
new file mode 100644
index 000000000..95c3a859c
--- /dev/null
+++ b/docs/dist/examples/tracing/lib/TraceMyClasses.java
@@ -0,0 +1,67 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.lib;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.io.FileNotFoundException;
+
+aspect TraceMyClasses extends AbstractTrace {
+ /**
+ * The application classes
+ */
+ pointcut classes(): within(TwoDShape) || within(Circle) || within(Square);
+ /**
+ * The constructors in those classes - but only the ones with 3
+ * arguments.
+ */
+ pointcut constructors(): execution(new(double, double, double));
+ /**
+ * This specifies all the message executions.
+ */
+ pointcut methods(): execution(* *(..));
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] _args) {
+ final String[] args = _args;
+ new Thread() {
+ public void run() {
+ TraceMyClasses.aspectOf().initStream(System.err);
+ ExampleMain.main(args);
+ }
+ }.start();
+
+ new Thread() {
+ public void run() {
+ try {
+ TraceMyClasses.aspectOf().initStream(new PrintStream(new FileOutputStream("AJTRACETEST")));
+ }
+ catch (FileNotFoundException e) {}
+ ExampleMain.main(args);
+ }
+ }.start();
+ }
+}
diff --git a/docs/dist/examples/tracing/version1/Trace.java b/docs/dist/examples/tracing/version1/Trace.java
new file mode 100644
index 000000000..eef96df51
--- /dev/null
+++ b/docs/dist/examples/tracing/version1/Trace.java
@@ -0,0 +1,83 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version1;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides some basic functionality for printing trace messages
+ * into a stream.
+ *
+ */
+public class Trace {
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 0;
+ protected static PrintStream stream = null;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ public static void initStream(PrintStream s) {
+ stream = s;
+ }
+
+ /**
+ * Prints an "entering" message. It is intended to be called in the
+ * beginning of the blocks to be traced.
+ */
+ public static void traceEntry(String str) {
+ if (TRACELEVEL == 0) return;
+ if (TRACELEVEL == 2) callDepth++;
+ printEntering(str);
+ }
+
+ /**
+ * Prints an "exiting" message. It is intended to be called in the
+ * end of the blocks to be traced.
+ */
+ public 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(" ");
+ }
+}
diff --git a/docs/dist/examples/tracing/version1/TraceMyClasses.java b/docs/dist/examples/tracing/version1/TraceMyClasses.java
new file mode 100644
index 000000000..b4a97ee31
--- /dev/null
+++ b/docs/dist/examples/tracing/version1/TraceMyClasses.java
@@ -0,0 +1,75 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version1;
+
+/**
+ *
+ * This class connects the tracing functions in the Trace class with
+ * the constructors and methods in the application classes.
+ *
+ */
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+aspect TraceMyClasses {
+ /**
+ * Application classes.
+ */
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(): myClass() && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ /**
+ * Prints trace messages before and after executing constructors.
+ */
+ before (): myConstructor() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * Prints trace messages before and after executing methods.
+ */
+ before (): myMethod() {
+ Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ Trace.traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
+
diff --git a/docs/dist/examples/tracing/version2/Trace.java b/docs/dist/examples/tracing/version2/Trace.java
new file mode 100644
index 000000000..cd631e278
--- /dev/null
+++ b/docs/dist/examples/tracing/version2/Trace.java
@@ -0,0 +1,123 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version2;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides support for printing trace messages into a stream.
+ * Trace messages are printed before and after constructors and methods
+ * are executed.
+ * It defines one abstract crosscut for injecting that tracing functionality
+ * into any application classes.
+ * To use it, provide a subclass that concretizes the abstract crosscut.
+ */
+abstract aspect Trace {
+
+ /*
+ * Functional part
+ */
+
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 2;
+ protected static PrintStream stream = System.err;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ 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(" ");
+ }
+
+
+ /*
+ * Crosscut part
+ */
+
+ /**
+ * Application classes - left unspecified.
+ * Subclasses should concretize this pointcut with class names.
+ */
+ abstract pointcut myClass();
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(): myClass() && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ pointcut myMethod(): myClass() && execution(* *(..));
+
+ /**
+ * Prints trace messages before and after executing constructors.
+ */
+ before(): myConstructor() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myConstructor() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+
+ /**
+ * Prints trace messages before and after executing methods.
+ */
+ before(): myMethod() {
+ traceEntry("" + thisJoinPointStaticPart.getSignature());
+ }
+ after(): myMethod() {
+ traceExit("" + thisJoinPointStaticPart.getSignature());
+ }
+}
diff --git a/docs/dist/examples/tracing/version2/TraceMyClasses.java b/docs/dist/examples/tracing/version2/TraceMyClasses.java
new file mode 100644
index 000000000..a3ae99e95
--- /dev/null
+++ b/docs/dist/examples/tracing/version2/TraceMyClasses.java
@@ -0,0 +1,43 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version2;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+/**
+ *
+ * This class concretizes the abstract crosscut in Trace,
+ * applying the trace facility to these application classes.
+ *
+ */
+public aspect TraceMyClasses extends Trace {
+ pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
diff --git a/docs/dist/examples/tracing/version3/Trace.java b/docs/dist/examples/tracing/version3/Trace.java
new file mode 100644
index 000000000..8fc9d8613
--- /dev/null
+++ b/docs/dist/examples/tracing/version3/Trace.java
@@ -0,0 +1,123 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version3;
+
+import java.io.PrintStream;
+
+/**
+ *
+ * This class provides support for printing trace messages into a stream.
+ * Trace messages are printed before and after constructors and methods
+ * are executed.
+ * The messages are appended with the string representation of the objects
+ * whose constructors and methods are being traced.
+ * It defines one abstract pointcut for injecting that tracing functionality
+ * into any application classes.
+ *
+ */
+abstract aspect Trace {
+
+ /*
+ * Functional part
+ */
+
+ /**
+ * There are 3 trace levels (values of TRACELEVEL):
+ * 0 - No messages are printed
+ * 1 - Trace messages are printed, but there is no indentation
+ * according to the call stack
+ * 2 - Trace messages are printed, and they are indented
+ * according to the call stack
+ */
+ public static int TRACELEVEL = 0;
+ protected static PrintStream stream = null;
+ protected static int callDepth = 0;
+
+ /**
+ * Initialization.
+ */
+ 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("--> " + str);
+ }
+
+ private static void printExiting(String str) {
+ printIndent();
+ stream.println("<-- " + str);
+ }
+
+
+ private static void printIndent() {
+ for (int i = 0; i < callDepth; i++)
+ stream.print(" ");
+ }
+
+
+ /*
+ * Crosscut part
+ */
+
+ /**
+ * Application classes - left unspecified.
+ */
+ abstract pointcut myClass(Object obj);
+ /**
+ * The constructors in those classes.
+ */
+ pointcut myConstructor(Object obj): myClass(obj) && execution(new(..));
+ /**
+ * The methods of those classes.
+ */
+ // toString is called from within our advice, so we shouldn't
+ // advise its executions. But if toString is overridden, even
+ // this might not be enough, so we might want
+ // && !cflow(execution(String toString()))
+ 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);
+ }
+}
diff --git a/docs/dist/examples/tracing/version3/TraceMyClasses.java b/docs/dist/examples/tracing/version3/TraceMyClasses.java
new file mode 100644
index 000000000..c986d2615
--- /dev/null
+++ b/docs/dist/examples/tracing/version3/TraceMyClasses.java
@@ -0,0 +1,46 @@
+/*
+
+Copyright (c) Xerox Corporation 1998-2002. All rights reserved.
+
+Use and copying of this software and preparation of derivative works based
+upon this software are permitted. Any distribution of this software or
+derivative works must comply with all applicable United States export control
+laws.
+
+This software is made available AS IS, and Xerox Corporation makes no warranty
+about the software, its performance or its conformity to any specification.
+
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+|<--- this code is formatted to fit into 80 columns --->|
+
+*/
+
+package tracing.version3;
+
+import tracing.TwoDShape;
+import tracing.Circle;
+import tracing.Square;
+import tracing.ExampleMain;
+
+/**
+ *
+ * This class concretizes the abstract crosscut in Trace,
+ * applying the trace facility to these application classes.
+ *
+ */
+public aspect TraceMyClasses extends Trace {
+ pointcut myClass(Object obj):
+ this(obj) &&
+ (within(TwoDShape) || within(Circle) || within(Square));
+
+ /**
+ * A main function for testing the trace aspect.
+ */
+ public static void main(String[] args) {
+ Trace.TRACELEVEL = 2;
+ Trace.initStream(System.err);
+ ExampleMain.main(args);
+ }
+}
+
diff --git a/docs/faq/faq.xml b/docs/faq/faq.xml
new file mode 100644
index 000000000..63dc386e2
--- /dev/null
+++ b/docs/faq/faq.xml
@@ -0,0 +1,3397 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "../../lib/docbook/docbook-dtd/docbookx.dtd">
+
+<?xml-stylesheet type="text/css"
+ href="../../style.css"?>
+<!-- `copy-to-register' (C-x r s) then `insert-register' (C-x r i).
+ <qandaentry>
+ <question id="q:XX" xreflabel="Q:XX">
+ <para></para>
+ </question>
+
+ <answer>
+ <para></para>
+ </answer>
+ </qandaentry>
+-->
+<article class="faq">
+ <title>Frequently Asked Questions about AspectJ</title>
+ <para>Copyright (c) 1997-2001 Xerox Corporation,
+ 2002 Palo Alto Research Center, Incorporated. All rights reserved.
+ </para>
+ <!-- todo Update me! -->
+ <para>Last updated on the web November 26, 2002.
+ </para>
+ <para>
+
+ For a list of recently-updated FAQ entries, see <xref linkend="q:faqchanges"/>
+ AspectJ 1.1 is currently in development, and
+ some answers may change after it is released;
+ for more information, see the
+ <ulink url="http://aspectj.org/doc/readme11/index.html">AspectJ 1.1 README</ulink>.
+ This is a web-only distribution of the FAQ; the 1.0 documentation bundle
+ contains an earlier version.
+ </para>
+ <qandaset defaultlabel="number">
+ <qandadiv id="overview" xreflabel="Overview">
+ <title>Overview</title>
+ <qandaentry>
+ <question id="q:whatisaj" xreflabel="Q:What is AspectJ?">
+ <para>What is AspectJ?</para>
+ </question>
+ <answer>
+ <para>
+ AspectJ(tm) is a simple and practical extension to the
+ Java(tm) programming
+ language that adds to Java aspect-oriented programming (AOP)
+ capabilities. AOP allows developers to reap the benefits of
+ modularity for concerns that cut across the natural units of
+ modularity. In object-oriented programs like Java, the natural unit
+ of modularity is the class. In AspectJ, aspects modularize concerns that
+ affect more than one class.
+ </para>
+ <para> AspectJ includes a compiler (<literal>ajc</literal>), a
+ debugger (<literal>ajdb</literal>), a documentation generator
+ (<literal>ajdoc</literal>), a program structure browser
+ (<literal>ajbrowser</literal>), and integration
+ with Eclipse, Sun-ONE/Netbeans, GNU Emacs/XEmacs, JBuilder, and Ant.
+ </para>
+ <para>You compile your program using the AspectJ compiler (perhaps using
+ the supported development environments) and then run it, supplying
+ a small (&lt; 100K) runtime library.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:benefits"
+ xreflabel="Q:What are the benefits of using AspectJ?">
+ <para>What are the benefits of using AspectJ?</para>
+ </question>
+ <answer>
+ <para>AspectJ can be used to improve the modularity of software
+ systems.
+ </para>
+ <para> Using ordinary Java, it can be difficult to modularize design
+ concerns such as
+ </para>
+ <itemizedlist>
+ <listitem><para>system-wide error-handling</para></listitem>
+ <listitem><para>contract enforcement</para></listitem>
+ <listitem><para>distribution concerns</para></listitem>
+ <listitem><para>feature variations</para></listitem>
+ <listitem><para>context-sensitive behavior</para></listitem>
+ <listitem><para>persistence</para></listitem>
+ <listitem><para>testing</para></listitem>
+ </itemizedlist>
+ <para>The code for these concerns tends to be spread out across the
+ system. Because these concerns won't stay inside of any one module
+ boundary, we say that they <emphasis>crosscut</emphasis> the
+ system's modularity.
+ </para>
+ <para>AspectJ adds constructs to Java that enable the modular
+ implementation of crosscutting concerns. This ability is
+ particularly valuable because crosscutting concerns tend to be both
+ complex and poorly localized, making them hard to deal with.
+ </para>
+ <!--
+ <para>Initial studies have shown code size reductions of up to 40%
+ and programmer productivity gains of 20%-40%. These studies were in
+ an earlier version of the language and only for small sample sizes.
+ So while the results are encouraging, they aren't conclusive. We
+ intend to run a new set of studies once the current phase of
+ language development stabilizes.</para>
+-->
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compability"
+ xreflabel="Q:Can AspectJ work with any Java program?">
+ <para>Can AspectJ work with any Java program?</para>
+ </question>
+ <answer>
+ <para>AspectJ has been designed as a <emphasis>compatible</emphasis>
+ extension to Java. By compatible, we mean
+ </para>
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry align="right">
+ <emphasis>upward compatible</emphasis>
+ </entry>
+ <entry>All legal Java programs are legal AspectJ
+ programs.
+ </entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis>platform
+ compatible
+ </emphasis>
+ </entry>
+ <entry>All legal AspectJ programs run on standard Java
+ virtual machines.
+ </entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis>tool
+ compatible
+ </emphasis>
+ </entry>
+ <entry>Existing tools can be extended to work with
+ AspectJ.
+ </entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis>programmer compatible</emphasis>
+ </entry>
+ <entry>Programming in AspectJ feels natural to Java
+ programmers.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <para>The AspectJ tools run on any Java 2 Platform compatible
+ platform. The AspectJ compiler produces classes that run
+ on any Java 1.1 (or later) compatible platform.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:license" xreflabel="Q:How is AspectJ licensed?">
+ <para>How is AspectJ licensed?</para>
+ </question>
+ <answer>
+ <para>The AspectJ tools are open-source software available under the
+ <ulink url="http://aspectj.org/MPL">Mozilla Public License 1.1</ulink>.
+ The documentation is available under a separate
+ <ulink url="http://aspectj.org/servlets/AJSite?channel=download&amp;subChannel=docTerms">
+ license
+ </ulink> that precludes for-profit or commercial
+ redistribution. Generally, we permit some usage for
+ internal presentations; please contact us at
+ <ulink url="mailto:support@aspectj.org?subject=Presentation%20materials">support@aspectj.org</ulink>
+ for permission.
+ </para>
+ <para>Most users only want to use AspectJ to build programs they distribute.
+ There are no restrictions here. When you distribute your program, be sure to
+ include all the runtime classes from the aspectjrt.jar for that version of AspectJ.
+ When distributing only the runtime classes, you need not provide any notice that
+ the program was compiled with AspectJ or includes binaries from the AspectJ project,
+ except as necessary to preserve the warranty disclaimers in our license.
+ Although the license does not require it, please email
+ <ulink url="mailto:support@aspectj.org">support@aspectj.org</ulink>
+ if you are shipping applications built with AspectJ; knowing that is
+ critical for ongoing support from our sponsors.
+ </para>
+ <para>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:project" xreflabel="Q:What is the AspectJ Project?">
+ <para>What is the AspectJ Project?</para>
+ </question>
+ <answer>
+ <para>AspectJ is based on over ten years of research at
+ <ulink url="http://www.parc.xerox.com">
+ Xerox Palo Alto Research Center
+ </ulink>
+ as funded by Xerox, a U.S. Government grant (NISTATP), and a
+ DARPA contract.
+ </para>
+ <para>It has evolved through open-source releases to a strong
+ user community.
+ The AspectJ team works closely with the community
+ to ensure AspectJ continues to evolve as an effective
+ aspect-oriented programming language and tool set.
+ </para>
+ <para>The latest release is 1.0.6 <!-- XXX todo Update me! -->
+ which can be downloaded from the AspectJ
+ <ulink url="http://aspectj.org/dl">download</ulink> page.
+ Further development is focused on supporting applications,
+ improving performance of the 1.0 compiler,
+ enhancing integration with IDEs,
+ and building the next generations of the language.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="quickstart" xreflabel="Quick Start">
+ <title>Quick Start</title>
+ <qandaentry>
+ <question id="q:requirements"
+ xreflabel="Q:What Java versions does AspectJ require and support?">
+ <para>
+ What Java versions does AspectJ require and support?
+ </para>
+ </question>
+ <answer>
+ <para>
+ The AspectJ compiler produces programs for any released version of the
+ Java platform (jdk1.1 and later). When running, your program classes must
+ be able to reach classes in the
+ small (&lt; 100K) runtime library (aspectjrt.jar) from the distribution.
+ The tools themselves require Java 2 (jdk 1.2) or later to run,
+ but the compiler can be set up to target any 1.1-compliant
+ version of the Java platform.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:install"
+ xreflabel="Q:How do I download and install AspectJ?">
+ <para>How do I download and install AspectJ?</para>
+ </question>
+ <answer>
+ <para>Go to AspectJ's
+ <ulink url="http://aspectj.org/dl">download web
+ page
+ </ulink> and choose which components you want download.
+ The <literal>jar</literal> files are installed by executing
+ </para>
+ <programlisting>
+ java -jar <emphasis>jar file name</emphasis>
+ </programlisting>
+ <para>Do <emphasis role="bold">not</emphasis> try to extract the
+ <literal>jar</literal> file contents and then attempt to execute
+ <literal>java org.aspectj.Main</literal>. (A
+ <classname>NoClassDefFoundError</classname> exception will be
+ thrown.) The AspectJ distribution is not designed to be installed
+ this way. Use the <literal>java -jar</literal> form shown above.
+ </para>
+ <para>The compressed <literal>tar</literal> files (suffix:
+ <literal>.tgz</literal>) are extracted by decompressing them with
+ <literal>tar</literal> or with <literal>WinZip</literal>.
+ </para>
+ <para>To uninstall, remove the files the installer wrote in your
+ file system. In most cases, you can delete the top-level install
+ directory (and all contained files), after you remove any
+ new or updated files you want to keep. On Windows, no
+ registry settings were added or changed, so nothing needs to be
+ undone. You may install over prior versions, but if the files are
+ locked the installer will warn you but still complete; in this case,
+ remove the locked files and reinstall.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:startUsingAJ"
+ xreflabel="Q: How should I start using AspectJ?">
+ <para>How should I start using AspectJ?</para>
+ </question>
+ <answer>
+ <para>Many users adopt AspectJ incrementally, first using it
+ to understand and validate their systems (relying on it only in
+ development) and then using it to implement crosscutting concerns
+ in production systems. AspectJ has been designed to make each
+ step discrete and beneficial.
+ </para>
+ <para>
+ In order of increasing reliance, you may use AspectJ:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <emphasis role="bold"> In the development
+ process
+ </emphasis> Use AspectJ to trace or log
+ interesting information. You can do this by adding
+ simple AspectJ code that performs logging or tracing.
+ This kind of addition may be removed ("unplugged") for
+ the final build since it does not implement a design
+ requirement; the functionality of the system is unaffected by
+ the aspect.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis role="bold">As an ancillary part of your
+ system
+ </emphasis> Use AspectJ to more completely and
+ accurately test the system.
+ Add sophisticated code that can check contracts,
+ provide debugging support, or implement test strategies.
+ Like pure development aspects, this code may also be
+ unplugged from production builds. However, the same code
+ can often be helpful in diagnosing failures in deployed
+ production systems, so you may design the functionality
+ to be deployed but disabled, and enable it when debugging.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <emphasis role="bold">As an essential part of your
+ system
+ </emphasis> Use AspectJ to modularize
+ crosscutting concerns in your system by design.
+ This uses AspectJ to implement logic integral to a system
+ and is delivered in production builds.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>This adoption sequence works well in practice and has been
+ followed by many projects.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:integrateWithDevTools"
+ xreflabel="Q: How well does AspectJ integrate with existing Java development tools?">
+ <para>How does AspectJ integrate with existing Java development
+ tools?
+ </para>
+ </question>
+ <answer>
+ <para>AspectJ products are designed to make it easy to integrate
+ AspectJ into an existing development process.
+ Each release includes
+ Ant taskdefs for building programs,
+ the AspectJ Development Environment (AJDE) for writing
+ aspects inside popular IDE's, and
+ command-line tools for compiling, documenting, and debugging.
+ </para>
+ <!-- ok to order for style, not priority? -->
+ <para>AspectJ provides replacements for standard Java tools:
+ <itemizedlist>
+ <listitem>
+ <para><literal>ajc</literal>, the AspectJ compiler,
+ runs on any Java 2 compatible platform, and produces classes
+ that run on any Java 1.1 (or later) compatible platform.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>ajdoc</literal> works like
+ Sun's <literal>javadoc</literal> API documentation generator
+ to produce HTML describing the semantics of Java and
+ AspectJ source files, including entries and cross-references
+ for the crosscutting structure.
+ </para>
+ </listitem>
+ <listitem>
+ <para><literal>ajdb</literal> is an aspect-aware debugger
+ akin to Java's <literal>jdb</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>The AspectJ Development Environment (AJDE)
+ enables programmers to view and navigate the crosscutting structures
+ in their programs, integrated with existing support in
+ popular Java IDE's for viewing and navigating object-oriented
+ structures. For many programmers this provides a deeper understanding
+ of how aspects work to modularize their concerns and permits them
+ to incrementally extend their development practices without
+ having to abandon their existing tools.
+ </para>
+ <para>
+ AJDE integrates with the following tools:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>Borland's JBuilder (versions 4 and 5)</para>
+ </listitem>
+ <listitem>
+ <para>Sun Microsystems' Forte for Java (versions 2 and 3),
+ and Netbeans 3.2
+ </para>
+ </listitem>
+ <listitem>
+ <para>Eclipse (version 2.0)</para>
+ </listitem>
+ <listitem>
+ <para>GNU Emacs (version 20.3) and XEmacs (version 21.1 on Unix
+ and 21.4 on Windows)
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The common functionality of AJDE is also available in
+ the stand-alone source code browser <literal>ajbrowser</literal>,
+ included in the tools distribution.
+ </para>
+ <para>AspectJ also supports building with Ant by providing
+ taskdef interfaces to the ajc and ajdoc tools.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="typicalprograms" xreflabel="Typical AspectJ programs">
+ <title>Typical AspectJ programs</title>
+ <qandaentry>
+ <question id="q:aspectsoptional"
+ xreflabel="Q:Are aspects always optional or non-functional parts of a program?">
+ <para>Are aspects always optional or non-functional parts of
+ a program?
+ </para>
+ </question>
+ <answer>
+ <para>No. Although AspectJ can be used in a way that allows AspectJ
+ code to be removed for the final build, aspect-oriented code is not
+ <emphasis>always</emphasis> optional or non-functional. Consider
+ what AOP really does: it makes the modules in a program correspond
+ to modules in the design. In any given design, some modules are
+ optional, and some are not.
+ </para>
+ <para>The examples directory included in the AspectJ distribution
+ contains some examples of the use aspects that are not optional.
+ Without aspects,
+ </para>
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry align="right">
+ <emphasis role="strong">bean</emphasis>
+ </entry>
+ <entry>Point objects would not be JavaBeans.</entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis role="strong">introduction</emphasis>
+ </entry>
+ <entry>Point objects would not be cloneable, comparable or
+ serializable.
+ </entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis role="strong">spacewar</emphasis>
+ </entry>
+ <entry>Nothing would be displayed.</entry>
+ </row>
+ <row>
+ <entry align="right">
+ <emphasis role="strong">telecom</emphasis>
+ </entry>
+ <entry>No calls would be billed.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:developmentAndProductionAspects"
+ xreflabel="Q:What is the difference between development and production aspects?">
+ <para>
+ What is the difference between development and production aspects?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Production aspects are delivered with the finished product,
+ while development aspects are used during the development process.
+ Often production aspects are also used during development.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:devAspects"
+ xreflabel="Q:What are some common development aspects?">
+ <para>
+ What are some common development aspects?
+ </para>
+ </question>
+ <answer>
+ <para>Aspects for logging, tracing, debugging, profiling
+ or performance monitoring, or testing.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:prodAspects"
+ xreflabel="Q:What are some common production aspects?">
+ <para>
+ What are some common production aspects?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Aspects for performance monitoring and diagnostic systems,
+ display updating or notifications generally, security,
+ context passing, and error handling.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="concepts" xreflabel="Basic AOP and AspectJ Concepts">
+ <title>Basic AOP and AspectJ Concepts</title>
+ <qandaentry>
+ <question id="q:crosscutting"
+ xreflabel="Q:What are scattering, tangling, and crosscutting?">
+ <para>What are scattering, tangling, and crosscutting?</para>
+ </question>
+ <answer>
+ <para>
+ "Scattering" is when similar code is distributed throughout many
+ program modules. This differs from a component being used by
+ many other components since
+ it involves the risk of misuse at each point and of inconsistencies
+ across all points. Changes to the implementation may require
+ finding and editing all affected code.
+ </para>
+ <para>"Tangling" is when two or more concerns are implemented in
+ the same body of code or component, making it more difficult to understand.
+ Changes to one implementation may cause unintended changes
+ to other tangled concerns.
+ </para>
+ <para>"Crosscutting" is how to characterize a concern than spans
+ multiple units of OO modularity - classes and objects. Crosscutting
+ concerns resist modularization using normal OO constructs, but
+ aspect-oriented programs can modularize crosscutting concerns.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:joinpoints"
+ xreflabel="Q: What are join points?">
+ <para>What are join points?</para>
+ </question>
+ <answer>
+ <para>Join points are well-defined points in the execution of a
+ program. Not every execution point is a join point: only those
+ points that can be used in a disciplined and principled manner are.
+ So, in AspectJ, the execution of a method call is a join point, but
+ "the execution of the expression at line 37 in file Foo.java" is
+ not.
+ </para>
+ <para>The rationale for restricting join points is similar to the
+ rationale for restricting access to memory (pointers) or
+ restricting control flow expressions (<literal>goto</literal>) in
+ Java: programs are easier to understand, maintain and extend
+ without the full power of the feature.
+ </para>
+ <para>AspectJ join points include reading or writing a field; calling
+ or executing an exception handler, method or constructor.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:pointcut"
+ xreflabel="Q; What is a pointcut?">
+ <para>
+ What is a pointcut?
+ </para>
+ </question>
+ <answer>
+ <para>A pointcut picks out
+ <link linkend="q:joinpoints">
+ join points
+ </link>. These join points are described by the pointcut
+ declaration. Pointcuts can be defined in classes or in aspects,
+ and can be named or be anonymous.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:advice"
+ xreflabel="Q:What is advice?">
+ <para>What is advice?</para>
+ </question>
+ <answer>
+ <para>Advice is code that executes at each
+ <link linkend="q:joinpoints">join point</link> picked out by a
+ <link linkend="q:pointcut">pointcut</link>. There are three
+ kinds of advice: before advice, around advice and after advice. As
+ their names suggest, before advice runs before the join point
+ executes; around advice executes before and after the join point;
+ and after advice executes after the join point. The power of
+ advice comes from the advice being able to access values in the
+ execution context of a pointcut.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:declarations"
+ xreflabel="Q:What are inter-type declarations?">
+ <para>What are inter-type declarations?</para>
+ </question>
+ <answer>
+ <para>AspectJ enables you to declare members and supertypes of another class
+ in an aspect, subject to Java's type-safety and access rules. These are
+ visible to other classes only if you declare them as accessible.
+ You can also declare compile-time errors and warnings based on pointcuts.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:whatisanaspect"
+ xreflabel="Q:What is an aspect?">
+ <para>What is an aspect?</para>
+ </question>
+ <answer>
+ <para>Aspects are a new class-like language element that has been
+ added to Java by AspectJ. Aspects are how developers encapsulate
+ concerns that cut across classes, the natural unit of modularity in
+ Java.
+ </para>
+ <para>Aspects are similar to classes because...
+ <itemizedlist>
+ <listitem><para>aspects have type</para></listitem>
+ <listitem>
+ <para>
+ aspects can extend classes and other aspects
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ aspects can be abstract or concrete
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ non-abstract aspects can be instantiated
+ </para>
+ </listitem>
+ <listitem>
+ <para>aspects can have static and non-static state and
+ behavior
+ </para>
+ </listitem>
+ <listitem>
+ <para>aspects can have fields, methods, and types
+ as members
+ </para>
+ </listitem>
+ <listitem>
+ <para>the members of non-privileged aspects follow the
+ same accessibility rules as those of classes
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>Aspects are different than classes because...
+ <itemizedlist>
+ <listitem>
+ <para>aspects can additionally include as members pointcuts,
+ advice, and inter-type declarations;
+ </para>
+ </listitem>
+ <listitem>
+ <para>aspects can be qualified by specifying the
+ context in which the non-static state is available
+ </para>
+ </listitem>
+ <listitem>
+ <para>aspects can't be used interchangeably with
+ classes
+ </para>
+ </listitem>
+ <listitem>
+ <para>aspects don't have constructors or finalizers,
+ and they cannot be created with the new operator;
+ they are automatically available as needed.
+ </para>
+ </listitem>
+ <listitem>
+ <para>privileged aspects can access private members of
+ other types
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="whyaop" xreflabel="Why AOP?">
+ <title>Why AOP?</title>
+ <qandaentry>
+ <question id="q:ccfromflaws"
+ xreflabel="Q:Are crosscutting concerns induced by flaws?">
+ <para>Are crosscutting concerns induced by flaws in parts of the
+ system design, programming language, operating system, etc. Or is
+ there something more fundamental going on?
+ </para>
+ </question>
+ <answer>
+ <para>AOP's fundamental assumption is that in any sufficiently
+ complex system, there will inherently be some crosscutting
+ concerns.
+ </para>
+ <para>So, while there are some cases where you could re-factor a
+ system to make a concern no longer be crosscutting, the AOP idea
+ is that there are many cases where that is not possible, or where
+ doing so would damage the code in other ways.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:definingaspectspercc"
+ xreflabel="Q:Does it really make sense to define aspects in terms of crosscutting?">
+ <para>Does it really make sense to define aspects in terms of
+ crosscutting?
+ </para>
+ </question>
+ <answer>
+ <para>Yes.</para>
+ <para>The short summary is that it is right to define AOP in terms of
+ crosscutting, because well-written AOP programs have clear
+ crosscutting structure. It would be a mistake to define AOP in
+ terms of "cleaning up tangling and scattering", because that isn't
+ particular to AOP, and past programming language innovations also
+ do that, as will future developments.
+ </para>
+ <para>Slides for a long talk on this topic are at
+ <ulink url="http://www.cs.ubc.ca/~gregor/vinst-2-17-01.zip">
+ http://www.cs.ubc.ca/~gregor/vinst-2-17-01.zip
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:domainspecific"
+ xreflabel="Q:Is AOP restricted to domain-specific applications?">
+ <para>Is AOP restricted to domain-specific
+ applications?
+ </para>
+ </question>
+ <answer>
+ <para>No. Some implementations of AOP are domain-specific, but
+ AspectJ was specifically designed to be general-purpose.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:whyaopifinterceptors"
+ xreflabel="Q:Why do I need AOP if I can use interceptors?">
+ <para>Why do I need AOP if I can use interceptors
+ (or JVMPI or ref
+ lection)?
+ </para>
+ </question>
+ <answer>
+ <para>There are many mechanisms people use now to implement
+ some crosscutting concerns. But they don't have a way to express
+ the actual structure of the program so you (and your tools)
+ can reason about it. Using a language enables you to express the
+ crosscutting in first-class constructs. You can not only avoid the
+ maintenance problems and structural requirements of some other
+ mechanisms, but also combine forms of crosscutting so that all
+ the mechanisms for a particular concern are one piece of code.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="related" xreflabel="Related Technology">
+ <title>Related Technology</title>
+ <qandaentry>
+ <question id="q:comparetonewforms"
+ xreflabel="Q:How does AspectJ compare to other new forms of programming?">
+ <para>
+ How does AspectJ compare to other new forms of programming?
+ </para>
+ </question>
+ <answer>
+ <para>There are many recent proposals for programming languages that
+ provide control over crosscutting concerns. Aspect-oriented
+ programming is an overall framework into which many of these
+ approaches fit. AspectJ is one particular instance of AOP,
+ distinguished by the fact that it was designed from the ground up
+ to be compatible with Java.
+ </para>
+ <para>See the
+ <ulink url="http://aspectj.org/relatedSites">Related
+ Sites
+ </ulink> page of the AspectJ web site for more
+ information.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compartoreflection"
+ xreflabel="Q:How do you compare the features of AspectJ with reflective systems?">
+ <para>How do you compare the features of AspectJ with
+ reflective systems?
+ </para>
+ </question>
+ <answer>
+ <para>Reflective and aspect-oriented languages have an important
+ similarity: both provide programming support for dealing with
+ crosscutting concerns. In this sense reflective systems proved
+ that independent programming of crosscutting concerns is
+ possible.
+ </para>
+ <para>But the control that reflection provides tends to be low-level
+ and extremely powerful. In contrast, AspectJ provides more
+ carefully controlled power, drawing on the rules learned from
+ object-oriented development to encourage a clean and understandable
+ program structure.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:comparetomixin"
+ xreflabel="Q:How do AspectJ features compare with those of mixin-based inheritance?">
+ <para>How do AspectJ features compare with those of mixin-based
+ inheritance?
+ </para>
+ </question>
+ <answer>
+ <para>Some features of AspectJ, such as introduction, are related to
+ <emphasis>mixin-based inheritance</emphasis>. But, in order to
+ support crosscutting, a core goal for AspectJ, AspectJ goes beyond
+ mixin-based inheritance.
+ </para>
+ <para>Firstly, an aspect imposes behavior on a class, rather than a
+ class requesting behavior from an aspect. An aspect can modify a
+ class without needing to edit that class. This property is
+ sometimes called <emphasis>reverse inheritance</emphasis>.
+ </para>
+ <para>Secondly, a single aspect can affect multiple classes in
+ different ways. A single paint aspect can add different paint
+ methods to all the classes that know how to paint, unlike mixin
+ classes.
+ </para>
+ <para>
+So mixin-based inheritance doesn't have the reverse inheritance
+property, and mixins affect every class that mixes them in the same.
+If I want to do something like SubjectObserverProtocol, I need two
+mixins, SubjectPartofSubjectObserverProtocol and ObserverPartof...
+In AspectJ, both halves of the protocol can be captured in a single
+aspect.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aopandxp"
+ xreflabel="Q:What is the relationship between AOP and
+ XP (extreme programming AKA agile methods)?">
+ <para>What is the relationship between AOP and
+ XP (extreme programming AKA agile methods)?
+ </para>
+ </question>
+ <answer>
+ <para>From a question on the user list:
+ <programlisting>
+> Anyone know the connections between AOP and Extreme Programming?
+> I am really confused. It seems AOP is a programming paradigm, which
+> is the next level of abstraction of OOP. Extreme Programming, however,
+> this is a lightweight software development process. One of the common
+> motivations of AOP and XP is designed to adopt to the requirement
+> changes, so that it can save the cost of software development.
+ </programlisting>
+ </para>
+ <para>
+ This is Raymond Lee's answer:
+ </para>
+ <para>
+ You're not really that confused. AOP and XP are orthogonal concepts,
+ although AOP can be used to help accomplish XP goals.
+ One of the goals of XP is to respond to changing requirements.
+ Another is to reduce the overall cost of development. These are
+ not necessarily the same thing.
+ </para>
+ <para>
+ One of the principles of XP that contribute to meeting those goals
+ is to maintain clean, simple designs. One of the criteria for clean,
+ simple designs is to factor out duplication from the code. Benefits
+ of removing duplication include the code being easier to understand,
+ better modularity of the design, lower costs of code changes, less
+ chance of conflicting changes when practicing collective code
+ ownership, etc.
+ </para>
+ <para>
+ Different types of duplication lend themselves to being addressed by
+ different design paradigms and language features. Duplicate snippets
+ of code can be factored out into methods. Duplicate methods can be
+ factored out to common classes, or pushed up to base classes.
+ Duplicate patterns of methods and their use can be factored out to
+ mechanisms of classes and methods (i.e. instantiations of design
+ patterns).
+ </para>
+ <para>
+ AOP addresses a type of duplication that is very difficult to handle
+ in the other common paradigms, namely cross-cutting concerns. By
+ factoring out duplicate cross-cutting code into aspects, the target
+ code becomes simpler and cleaner, and the cross-cutting code becomes
+ more centralized and modular.
+ </para>
+ <para>
+ So, AOP as a paradigm, and the associated tools, gives an XPer, or
+ anyone wanting to remove duplication from the code base, a powerful
+ way to remove a form of duplication not easily addressed until now.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aspectjandcsharp"
+ xreflabel="Q:Will you support C#?">
+ <para>Will you support C#?</para>
+ </question>
+ <answer>
+ <para>Not at this time. Although the resemblances between C# and Java
+ means it would probably be a fairly straightforward matter to take
+ the AspectJ language design and produce AspectC#, our current focus
+ is only on supporting effective uses of AspectJ.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="adoption" xreflabel="Deciding to adopt AspectJ">
+ <title>Deciding to adopt AspectJ</title>
+ <qandaentry>
+ <question id="q:productplans"
+ xreflabel="Q:Is it safe to use AspectJ in my product plans??">
+ <para>
+ Is it safe to use AspectJ in my product plans?
+ </para>
+ </question>
+ <answer>
+ <para>You may use AspectJ in your product or project with little
+ risk. Several factors play a role in reducing the risk of adopting
+ this new technology:
+ <itemizedlist>
+ <listitem>
+ <para>AspectJ is an <emphasis>addition</emphasis> to
+ Java, and can be incrementally introduced into a project
+ in a way that limits risk.
+ See <xref linkend="q:startUsingAJ"/> for
+ some suggestions on how to do this.
+ </para>
+ </listitem>
+ <listitem>
+ <para>The AspectJ compiler accepts standard Java as
+ input and produces standard Java bytecode as output. An
+ optional mode produces standard Java source code which may
+ then be compiled with any compliant Java compiler, e.g. Sun's
+ <literal>javac</literal> compiler
+ or IBM's <literal>jikes</literal> compiler.
+ </para>
+ </listitem>
+ <listitem>
+ <para>AspectJ is available under the
+ <ulink url="http://aspectj.org/MPL">Mozilla Public License</ulink>,
+ a non-proprietary, open source license. This ensures that
+ AspectJ will continue to evolve and be available, regardless
+ of the fate of any particular organization involved with
+ AspectJ.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Removing AspectJ from your program is not
+ difficult, although you will lose the flexibility and
+ economy that AspectJ provided.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:effectonsize"
+ xreflabel="Q:What is the effect of using AspectJ on the source code size of programs?">
+ <para>What is the effect of using AspectJ on the source code
+ size of programs?
+ </para>
+ </question>
+ <answer>
+ <para>Using aspects reduces, as a side effect, the number of source
+ lines in a program. However, the major benefit of using aspects
+ comes from <emphasis>improving</emphasis> the modularity of a
+ program, not because the program is smaller. Aspects gather into a
+ module concerns that would otherwise be scattered across or
+ duplicated in multiple classes.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:effectonperformance"
+ xreflabel="Q:Does AspectJ add any performance overhead?">
+ <para>
+ Does AspectJ add any performance overhead?
+ </para>
+ </question>
+ <answer>
+ <para>The issue of performance overhead is an important one. It is
+ also quite subtle, since knowing what to measure is at least as
+ important as knowing how to measure it, and neither is always
+ apparent.
+ </para>
+ <para>There is currently no benchmark suite for AOP languages in
+ general nor for AspectJ in particular. It is probably too early to
+ develop such a suite because AspectJ needs more maturation of the
+ language and the coding styles first. Coding styles really drive
+ the development of the benchmark suites since they suggest what is
+ important to measure.
+ </para>
+ <para>In the absence of a benchmark suite, AspectJ probably has an
+ acceptable performance for everything except non-static advice.
+ Introductions and static advice should have extremely small
+ performance overheads compared to the same functionality
+ implemented by hand.
+ </para>
+ <para>The <literal>ajc</literal> compiler will use static typing information
+ to only insert those checks that are absolutely necessary. Unless you use
+ 'thisJoinPoint' or 'if', then the only dynamic checks that will be
+ inserted by ajc will be 'instanceof' checks which are generally quite fast.
+ These checks will only be inserted when they can not be inferred from
+ the static type information.
+ </para>
+ <para>If you'd like to measure the performance be sure to write code
+ fragments in AspectJ and compare them to the performance of the
+ corresponding code written without AspectJ. For example, don't
+ compare a method with before/after advice that grabs a lock to just
+ the method. That would be comparing apples and oranges. Also be
+ sure to watch out for JIT effects that come from empty method
+ bodies and the like. Our experience is that they can be quite
+ misleading in understanding what you've measured.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:modularityviolations"
+ xreflabel="Q:I've heard that AspectJ leads to modularity violations. Does it?">
+ <para>
+ I've heard that AspectJ leads to modularity violations. Does it?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Well I haven't yet seen a language in which you can't write bad code!
+ </para>
+ <para>
+ But seriously, most AspectJ users find that just like when they learned
+ OO, it takes a while to really get the hang of it. They tend to start
+ in the usual way, by copying canonical examples and experimenting with
+ variations on them.
+ </para>
+ <para>
+ But users also find that rather than being dangerous, AspectJ helps them
+ write code that is more clear and has better encapsulation -- once they
+ understand the kind of modularity AspectJ supports. There are several
+ good papers that talk about this (see below), but here's a basic point
+ to keep in mind: when properly used, AspectJ makes it possible program
+ in a modular way, something that would otherwise be spread throughout
+ the code. Consider the following code, adapted from the AspectJ tutorial:
+ </para>
+ <programlisting>
+aspect PublicErrorLogging {
+ Log log = new Log();
+
+ pointcut publicInterface(Object o):
+ call(public * com.xerox.*.*(..)) &amp;&amp; target(o);
+
+ after(Object o) throwing (Error e): publicInterface(o) {
+ log.write(o, e);
+ }
+}
+ </programlisting>
+ <para>
+ The effect of this code is to ensure that whenever any public method of
+ an interface or class in the <literal>com.xerox</literal> package
+ throws an error, that error is logged before being thrown to its caller.
+ </para>
+ <para>
+ Of course in the alternative implementation a large number of methods
+ have a try/catch around their body.
+ </para>
+ <para>
+ The AspectJ implementation of this crosscutting concern is clearly
+ modular, whereas the other implementation is not. As a result, if you
+ want to change it, its easier in the AspectJ implementation. For
+ example, if you also want to pass the name of the method, or its
+ arguments to <literal>log.write</literal>, you only have to edit
+ one place in the AspectJ code.
+ </para>
+ <para>
+ This is just a short example, but I hope it shows how what happens
+ with AOP and AspectJ is that the usual benefits of modularity are
+ achieved for crosscutting concerns, and that leads to better code,
+ not more dangerous code.
+ </para>
+ <para>
+ One paper someone else just reminded me of that talks some more
+ about this is:
+ <ulink url="http://www.cs.ubc.ca/~kdvolder/Workshops/OOPSLA2001/submissions/12-nordberg.pdf">
+ http://www.cs.ubc.ca/~kdvolder/Workshops/OOPSLA2001/submissions/12-nordberg.pdf
+ </ulink>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:encapsulation"
+ xreflabel="Q:Why does AspectJ permit aspects to access and add members of another type?">
+ <para>
+ Why does AspectJ permit aspects to access and add members of another type?
+ Isn't that violating OO encapsulation?
+ </para>
+ </question>
+ <answer>
+ <para>In the spirit of Smalltalk, we have decided to give more power
+ to the language in order to let the user community experiment and
+ discover what is right. To date this has proven to be a successful
+ strategy because it has permitted the construction of many useful
+ aspects that crosscut the internal state of an object, and as such
+ need access the its private members. However, we are not
+ discounting that some sort of restrictions are useful, rather, we
+ are seeking input from the community in order to decide on what
+ these restrictions should be.
+ </para>
+ <para>
+ In that light, our position on encapsulation is :
+ </para>
+ <itemizedlist>
+ <listitem><para>we respect Java's visibility rules</para></listitem>
+ <listitem><para>we also provide open-classes, a mature OO technology</para></listitem>
+ <listitem><para>we provide "privileged" access if you really need it.</para></listitem>
+ </itemizedlist>
+ <para>
+ Introducing parents or members to classes is a well-studied OO technique
+ known as open classes.
+ </para>
+ <para>
+ Open classes have been used in many languages prior to AspectJ,
+ including CLOS, Python, Smalltalk, Objective-C, and others.
+ Building from Java, introduction in AspectJ provides better
+ name hygiene and access control than prior languages.
+ Introduced code obeys all of Java's normal accessibility rules
+ for its lexical location in the aspect that it is introduced from.
+ Such code can not even see, much less access, private members of
+ the class it is introduced into. Further, introductions can be
+ declared private to the aspect, so they are not visible to
+ other clients of the class.
+ </para>
+ <para>
+ Privileged aspects do permit access to private members of another
+ class. They are a response to the very few cases where developers
+ genuinely need such access (typically for testing purposes where it
+ access is necessary), but it would be more risky to open access by
+ putting the aspect in the same package, adding test code, or changing
+ access in the target class. We recommend using privileged aspects
+ only as necessary, and believe that marking them "privileged" makes
+ any potential misuse apparent.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aspectjandj2ee"
+ xreflabel="Q:Can I use AspectJ with J2EE?">
+ <para>Can I use AspectJ with J2EE?</para>
+ </question>
+ <answer>
+ <para>
+ Consider the component types in J2EE:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Servlet: AspectJ works well within servlets
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ JSP: It is possible to use AspectJ to affect code in JSPs by precompiling
+ them into Java sources and compiling these with ajc. This can be used, e.g., to
+ customize displays by turning on and off custom JSP taglibs. The mapping from a
+ given jsp source to java package and class name is not standardized, which means
+ doing this imposes dependencies on specific container versions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ EJB: AspectJ supports a wide variety of aspects for EJBs. It can be used for
+ logging, tracing, debugging, error handling by layers, correlated method-level
+ interception (e.g., chargebacks), metering, fine-grained transactions, etc.
+ Indeed, it can be used to enforce adherence to coding restrictions within an
+ EJB (e.g., not using java.io, creating a class loader, or listening on
+ sockets) using <literal>declare error</literal>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The basic limitations are that there is no built-in support for writing J2EE
+ analogs for AspectJ extensions to Java, like distributed aspects, distributed
+ cflow, or managing state between invocations. These don't prevent one from using
+ AspectJ to do useful intra-container implementation, nor need they prevent one
+ from building distributed support, state management, and inter-component
+ implementations that leverage AspectJ. It just takes some work. In more detail:
+ </para>
+ <para>
+ All AspectJ implementations may define "code the implementation controls".
+ The AspectJ 1.0 implementation defines this as the files passed to the compiler
+ (AspectJ 1.1 will also support bytecode weaving).
+ </para>
+ <para>
+ Some advice on EJB operations will generate methods that confuse ejb compilers.
+ To avoid this problem, you can use the -XaddSafePrefix flag when compiling with ajc.
+ </para>
+ <para>
+ EJB components may be invoked remotely, and containers may passivate and
+ pool EJB's. Servlets have similar limitations, and in both cases the
+ lifespan of the defining class loader is implementation-dependent
+ (though it must span the operation of a particular request).
+ </para>
+ <para>
+ Being limited by lifecycle and namespace, the AspectJ 1.0 implementation
+ supports aspects that operate through non-remote invocations during the lifetime
+ of the namespace for a particular
+ deployment unit compiled in its entirety by the ajc compiler.
+ This means AspectJ supports common aspects only within a single local runtime
+ namespace (usually implemented as a class loader hierarchy).
+ </para>
+ <para>
+ Further, AspectJ recognizes language-level join points (object initialization,
+ method calls, etc.), not their EJB analogs (ejb find or create methods...).
+ These lead to the following consequences:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Issingleton aspects (the default) are limited to the lifetime of
+ the defining class loader, which in some implementations may not span
+ multiple invocations of the same application or EJB component.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ EJB lifecycles are different from object lifecycles, so perthis
+ and pertarget aspects will make little sense. They do not work
+ in the current implementation, which uses synchronized methods
+ to ensure a correct association in threaded environments
+ (EJB's may not have synchronized methods).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Percflow or percflowbelow aspects are restricted to a chain of
+ non-remote invocations. While EJB 2.0 permits declaring an interface
+ local, this information is not available to the AspectJ compiler today.
+ For same reasons as stated above fore perthis, these will not work even
+ in the EJB container.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Evaluation of cflow or cflowbelow pointcuts will be valid only
+ with respect to a chain of non-remote invocations.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ In addition, any AspectJ code should respect EJB operations:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ The EJB container accesses EJB component fields directly, i.e.,
+ in code outside the control of the compiler. There is no join point for
+ these accesses, and hence no way to write a pointcut to advise that access.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The EJB container may pool EJB components, so any initialization
+ join points may run once per component constructed, not once per
+ component initialized for purposes of a client call.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ The EJB container is permitted to change class loaders, even
+ between invocations of a particular EJB component (by passivating and
+ activating with a new class loader). In this case, instances of singleton
+ aspects will not operate over multiple invocations of the component, or that
+ static initialization join point recur for a given class as it is re-loaded.
+ This behavior depends on the container implementation.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aspectjandgj"
+ xreflabel="Q:Can I use AspectJ with Generic Java?">
+ <para>Can I use AspectJ with Generic Java?</para>
+ </question>
+ <answer>
+ <para>At this time, unfortunately not. The two compilers are just not
+ at all compatible. In an ideal world, there would be a wonderful
+ Open Source extensible compiler framework for Java that both GJ and
+ AspectJ would be built on top of, and they would seamlessly
+ interoperate along with all other extensions to Java that you might
+ be interested in, but that's not the case (yet?).
+ </para>
+ <para>However, on 09 October 2000, the Java Community Process
+ approved a proposal to add generic types to Java that is largely
+ based on GJ (JSR 14). A draft specification was submitted for
+ public review, which closed on 01 August 2001, and a
+ <ulink url="http://plan9.bell-labs.com/who/wadler/pizza/gj/">
+ prototype implementation
+ </ulink> has been released.
+ </para>
+ <para>We are committed to moving very rapidly to add support for
+ generic types in AspectJ when generic types become part of the Java
+ language specification. Everyone on the AspectJ team is looking
+ forward to this, because we too would really like to be able to
+ write code that includes both aspects and generic types.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aopinjava"
+ xreflabel="Q: Are you working to put AOP into Java?">
+ <para> Are you working to put AOP into Java?
+ It seems that every AOP toolset currently uses proprietary mechanisms
+ to describe point-cuts, etc.
+ </para>
+ </question>
+ <answer>
+ <para>
+ We are working on standardization, but it's
+ a question of timing/ripeness (imagine going from thousands of users
+ to millions). (See <xref linkend="q:standardization"/>.) We believe
+ AspectJ addresses this question in the best way possible now:
+ <itemizedlist>
+ <listitem>
+ <para>
+ It's open-source. Rather than being proprietary or controlled by a
+ vendor, it's available for anybody to use and build upon, forever.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ AspectJ is not a set of mechanisms, it's a language. It is currently
+ implemented using certain techniques, but there's nothing that prevents
+ it from being implemented with other techniques. That means users can
+ adopt the language with confidence that implementations will get better.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ There is no engineering need to change Java. The AspectJ language uses
+ the join point model already in Java, so there is no need to extend the
+ programming model. Our implementation produces valid Java bytecode, which
+ runs in any compliant J2SE VM and supports standard debuggers for those VM's
+ that support JSR-45 (debugging support for multi-language/multi-file sources).
+ This is a huge benefit to Sun since Sun must be extremely cautious
+ about extensions to the language or VM; before adopting AOP, Sun should
+ demand the kind of actual-proof that AspectJ implementations offer.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ On the issue of "proprietary mechanisms to describe pointcuts, etc.": Any AOP
+ has to have some language to describe pointcuts and the like ("pointcuts"
+ of course being the AspectJ term). Users would like to have one language
+ (to avoid having to learn or transform between many languages) and the
+ choice of multiple implementations (tailored for a configuration, subject
+ to competitive pressure, etc.). That's what AspectJ offers.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ That said, we believe the AspectJ extensions to Java could form the basis
+ for bringing AOP to Java; when that happens, there will be engineering
+ opportunities to make the implementation and tool support better.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:support"
+ xreflabel="Q: What kind of support is available?">
+ <para>What kind of support is available?</para>
+ </question>
+ <answer>
+ <para>
+ The AspectJ users mailing list provides an
+ informal network of AspectJ experts. To subscribe,
+ visit the <ulink url="http://aspectj.org/servlets/AJSite?channel=userCommunity&amp;subChannel=mailingLists">Mailing Lists</ulink>
+ page of the AspectJ web site.
+ </para>
+ <para>If you have a problem that is not a bug, you may email
+ the AspectJ team at
+ <ulink url="mailto:support@aspectj.org">support@aspectj.org</ulink>.
+ You may view and submit bug reports and feature requests at
+ <ulink url="http://aspectj.org/bugs">http://aspectj.org/bugs</ulink>.
+ </para>
+ <para>Members of the AspectJ team are available to work with users in
+ more depth on both program design and implementation issues.
+ The team also presents educational courses and speakers for
+ interested groups and offers commercial support
+ and consulting for businesses.
+ Please contact the
+ <ulink url="mailto:support@aspectj.org">AspectJ team</ulink>.
+ with your request.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="compiler" xreflabel="Using the AspectJ compiler">
+ <title>Using the AspectJ compiler</title>
+ <qandaentry>
+ <question id="q:requiredsources"
+ xreflabel="Q:What files do I need to include when compiling AspectJ programs?">
+ <para>
+ What files do I need to include when compiling AspectJ programs?
+ </para>
+ </question>
+ <answer>
+ <para>You need to specify to the compiler the source files that
+ contain your aspects and the source files that contain the
+ types affected by your aspects.
+ See <xref linkend="q:knowWhenAspectsAffectClasses"/>.
+ The AspectJ compiler will not search the source path for types
+ that may be affected (unlike Javac and Jikes), and it only uses
+ aspects in source form.
+ </para>
+ <para>In some cases you should compile your entire system all at once.
+ If this is too slow, then you can try to make reasonable divisions
+ between sets of source files whose aspects do not interact to
+ achieve a shorter compile cycle (particularly for development
+ aspects). However, if you get any problems
+ or if you wish to run tests or do a release, you should recompile
+ the entire system.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:listingsources"
+ xreflabel="Q:Is there any other way to provide the file names to ajc?">
+ <para>I have to list many files in the command line to
+ compile with <literal>ajc</literal>. Is there any other way to
+ provide the file names to <literal>ajc</literal>?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Yes, use the argfile option to ajc. List source
+ files in a line-delimited text file and direct ajc to that
+ file using <literal>-argfile</literal> or <literal>@</literal>:
+ </para>
+ <programlisting>ajc @sources.lst
+ajc -argfile sources.lst
+ </programlisting>
+ <para>
+ For more information, see the <literal>ajc</literal> tool
+ section of the
+ <ulink url="devguide/index.html">
+ Development Environment Guide
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compilerVM"
+ xreflabel="Q: What Java virtual machine (JVM) do I use to run the
+ AspectJ compiler? ">
+ <para>What Java virtual machine (JVM) do I use to run the
+ AspectJ compiler?
+ </para>
+ </question>
+ <answer>
+ <para>Use the latest, greatest, fastest JVM you can get your hands on
+ for your platform. The compiler's performance is dependent on the
+ performance of the JVM it is running on, so the faster a JVM you
+ can find to run it on, the shorter your compile times will be. At a
+ minimum you need to use a Java 2 or later JVM to run the compiler.
+ We realize that this constraint can be a problem for users who
+ don't currently have a Java 2 JVM available. We're sorry for the
+ inconvenience, but we had to make the hard decision that the
+ advantages of being able to rely on Java 2 were worth the cost of
+ losing a number of developers who are working on platforms without
+ Java 2 support. Here is a list of starting places where you might
+ find support for your system.
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://java.sun.com/j2se/">Java 2
+ Platform, Standard Edition
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink
+ url="http://www.ibm.com/java/jdk/download/">
+ developerWorks : J
+ ava technology : Tools and products - Developer kits
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink
+ url="http://oss.software.ibm.com/developerworks/projects/jikes/?dwzone=opensource">
+ developerWorks : Open Source - Jikes Project
+ </ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <ulink url="http://java.sun.com/cgi-bin/java-ports.cgi">Java
+ Platform Ports
+ </ulink>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>The requirement of Java 2 support is only for
+ <emphasis>running</emphasis> the AspectJ compiler. The AspectJ
+ compiler can be used to build programs that will run on Java 1.1
+ (or probably even on Java 1.0) systems. This means that it can
+ build programs that will run on Macintosh, FreeBSD, and applets
+ that will run in Internet Explorer and Netscape Navigator that are
+ still not yet Java 2 compliant.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compilingForDifferentVMs"
+ xreflabel="Q: How to use ajc to compile for a different VM?">
+ <para>How can I use <literal>ajc</literal> to compile
+ programs for a JVM that is different from the one used to run it?
+ </para>
+ </question>
+ <answer>
+ <para>
+ <literal>ajc</literal> can be used to develop programs that are
+ targeted at the Java 1.1 platform, even though the
+ <literal>ajc</literal> compiler won't run on that platform. Here's
+ an example of using <literal>ajc</literal> in this sort of
+ cross-compilation mode (assuming a Windows platform with all the
+ default installation directories):
+ </para>
+ <programlisting>
+ajc -target 1.1 -bootclasspath c:\jdk1.1.7\lib\classes.zip \
+ -classpath c:\aspectj1.0\lib\aspectjrt.jar -extdirs "" \
+ -argfile jdk11system.lst
+ </programlisting>
+ <para>This same technique can be used if you want to run
+ <literal>ajc</literal> on a JDK 1.3 JVM (highly recommended) but
+ need to generate code for JDK 1.2. That would look something
+ like:
+ </para>
+ <programlisting>
+ajc -bootclasspath c:\jdk1.2\jre\lib\rt.jar \
+ -classpath c:\aspectj1.0\lib\aspectjrt.jar \
+ -extdirs c:\jdk1.2\jre\lib\ext
+ -argfile jdk12system.lst
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:assert"
+ xreflabel="Q:Does the ajc compiler support the assert keyword in Java 1.4?">
+ <para>Does the <literal>ajc</literal> compiler support
+ the <literal>assert</literal> keyword in Java 1.4?
+ </para>
+ </question>
+ <answer>
+ <para>Yes. As with <literal>Javac</literal>,
+ use the <literal>-source 1.4</literal> option as described
+ in the <literal>ajc</literal> tool section
+ of the
+ <ulink url="devguide/index.html">
+ Development Environment Guide
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:msjvm"
+ xreflabel="Q:Are there any issues using AspectJ with the Microsoft JVM?">
+ <para>Are there any issues using AspectJ with the Microsoft
+ JVM?
+ </para>
+ </question>
+ <answer>
+ <para>Since AspectJ requires Java 2 or later, it will not run on the
+ Microsoft JVM, which does not support Java 2.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:javacbytecode"
+ xreflabel="Q:Does ajc rely on javac for generating bytecode?">
+ <para>Does <literal>ajc</literal> rely
+ on <literal>javac</literal> for generating Java bytecode
+ (<literal>.class</literal>) files?
+ </para>
+ </question>
+ <answer>
+ <para> No. Some previous versions of AspectJ had this requirement,
+ and <literal>javac</literal> can still be used as
+ <literal>ajc</literal> back end by using the
+ <literal>-usejavac</literal> flag. You can also run <literal>ajc</literal>
+ in preprocessor mode to generate Java source
+ (<literal>.java</literal>) files to be compiled using
+ <literal>javac</literal> or another java compiler.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:parsergenerators"
+ xreflabel="Q:I noticed the AspectJ compiler doesn't use a parser generator. Why is that?">
+ <para>
+ I noticed the AspectJ compiler doesn't use a parser generator. Why is that?
+ </para>
+ </question>
+ <answer>
+ <para>
+ The PARSER for ajc is written by hand. This choice was made with full
+ awareness of the generator tools out there. (Jim had for example used
+ the excellent javacc tool for building the parser for JPython (now Jython)).
+ One of the reasons that AspectJ uses a hand-written parser is that using
+ javacc taught Jim about the LL-k design for parsers (pioneered by antlr).
+ As opposed to the state-machine parsers produced by yacc, these parsers are
+ very readable and writable by humans.
+ </para>
+ <para>
+ Antlr and javacc did not really suit the project:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Antlr's support for unicode in the lexer is still immature and this makes
+ using it with Java challenging. This was an even bigger issue 3 years ago
+ when we started on the Java implementation of ajc.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ While javacc is freely available, it is not Open Source. Depending on a
+ closed-source tool to build an Open Source compiler would reduce some
+ of the transparency and control of open-source.
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ There were also several things that were easier to implement with
+ a hand-written parser than with any of the exiting tools.
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ Semi-keywords -- it's important to us that
+ "every legal Java program is also a legal AspectJ program."
+ This wouldn't be true if we made 'before' and 'call' full keywords in
+ AspectJ. It is easier to support these sorts of semi-keywords with a
+ hand-written parser. (Note: ajc-1.0.x handles 'aspect' and 'pointcut'
+ slightly specially which can break a few unusual pure Java programs.
+ This is a compiler limitation that will be fixed in a future release.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Deprecated syntax warnings -- the syntax of AspectJ
+ changed many times from version 0.2 to the 1.0 release. It was easier
+ to provide helpful warning messages for these changes with our
+ hand-written parser.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Grammar modularity -- We like being able to have
+ AspectJParser extend JavaParser.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Part of the grammar for AspectJ is extremely hard for existing tools to
+ capture. This is the type pattern syntax, i.e. "com.xerox..*.*(..)".
+ The sort of case that gives standard parser generators fits is something
+ like "*1.f(..)" which no one would ever write, but which must be
+ supported for a consistent language.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="devtools" xreflabel="Integrating AspectJ into your development environment">
+ <title>Integrating AspectJ into your development environment</title>
+ <qandaentry>
+ <question id="q:knowWhenAspectsAffectClasses"
+ xreflabel="Q: How do I know which aspects affect a class when looking at that class's source code?">
+ <para>How do I know which aspects affect a class when looking
+ at that class's source code?
+ </para>
+ </question>
+ <answer>
+ <para>When you are working with the IDE support, you can get an
+ understanding of which aspects affect any class.
+ This enables AspectJ programmers to get the benefits of
+ modularizing crosscutting concerns while still having immediate
+ access to what aspects affect a class.
+ </para>
+ <para>For example, the
+ <ulink url="devguide/index.html">
+ Development Environment Guide
+ </ulink> section
+ on <literal>ajbrowser</literal> shows that you can list or navigate
+ between method and advice affecting that method and between a type
+ and declarations in an aspect on that type. (The IDE support may
+ have more features than <literal>ajbrowser</literal>, depending
+ on the IDE.)
+ </para>
+ <para>
+ When you are looking at documentation,
+ <literal>ajdoc</literal> will provide links from aspects and
+ advice to the affected code, but it provides less information
+ than the IDE support because it only parses declarations.
+ </para>
+ <para>
+ When you are running your program,
+ you can trace advice as it executes. This
+ enables you to identify advice on join points picked out
+ dynamically, which cannot be reflected precisely by IDE support.
+ </para>
+ <para>See <xref linkend="q:integrateWithDevTools"/> for more
+ information on which Java development environments are
+ supported.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:idesupport"
+ xreflabel="Q:What kind of IDE support is available for developing AspectJ programs?">
+ <para>What kind of IDE support is available for developing
+ AspectJ programs?
+ </para>
+ </question>
+ <answer>
+ <para>See <xref linkend="q:integrateWithDevTools"/></para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:hybridbuilds"
+ xreflabel="Q:Setting up hybrid builds">
+ <para>I want the aspects for development builds but
+ remove them for production builds. How can I set up the build
+ system so they are unpluggable? And so I use <literal>javac</literal>
+ in my production build?
+ </para>
+ </question>
+ <answer>
+ <para>
+ If you are using development-time-only aspects - aspects that only
+ exist when you are developing the code, not when you ship it -
+ you can use implement a hybrid build process by listing
+ the production source files into a javac-compliant argfile,
+ and the development source files in another ajc argfiles:
+ </para>
+ <programlisting>
+ -- file "production.lst":
+ One.java
+ two/Three.java
+ ...
+
+ -- file "tracing.lst":
+ trace/Library.java
+ Trace.java
+
+ -- file "development.lst":
+ @production.lst
+ @tracing.lst
+ </programlisting>
+ <para>
+ Then your development build can use <literal>ajc</literal>:
+ </para>
+ <programlisting>
+ ajc @development.lst
+ </programlisting>
+ <para>
+ And your development build can use
+ <literal>ajc</literal> or <literal>javac</literal>
+ or <literal>jikes</literal>:
+ </para>
+ <programlisting>
+ jikes @production.lst
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:idesupportplans"
+ xreflabel="Q:What plans are there to support my IDE?">
+ <para>What plans are there to support my IDE?</para>
+ </question>
+ <answer>
+ <para>
+ The AspectJ team directly provides components for JBuilder, Forte,
+ and Emacs. We also support the open-source AspectJ plugin project
+ at <ulink url="http://eclipse.org/ajdt">http://eclipse.org/ajdt</ulink>
+ which uses the AJDE API support for IDE's. We
+ are interested in supporting other developers as they use AJDE
+ to provide components for the following IDE's (roughly in
+ order of interest and viability).
+ <itemizedlist>
+ <title></title>
+ <listitem>
+ <para>IDEA/IntelliJ has an enthusiastic community and
+ the developers are working on an extensibility API
+ - <ulink url="http://intellij.com">http://intellij.com</ulink>
+ </para>
+ </listitem>
+ <listitem>
+ <para>jEdit comes from a very active open-source community.</para>
+ </listitem>
+ <listitem>
+ <para>
+ Oracle JDeveloper has an Extension SDK unfamiliar to us.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Together extensibility API is too limited</para>
+ </listitem>
+ <listitem>
+ <para>
+ VisualCafe may have a difficult extensibility API
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ IBM's VisualAge for Java is to be replaced with Eclipse
+ </para>
+ </listitem>
+ <listitem>
+ <para>Some have suggested Codeguide from Omnicore
+ <ulink url="http://www.omnicore.com">http://www.omnicore.com/</ulink>
+ </para>
+ </listitem>
+ <listitem><para>Visual SlickEdit ??</para></listitem>
+ <listitem><para>Kawa has been discontinued</para></listitem>
+ <listitem> <para>VIM has been suggested.</para></listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ If you would like to build support for an IDE, contact us so we can help.
+ To contribute or propose new IDE's, please
+ <ulink url="mailto:support@aspectj.org?subject=IDE%20Support:%20">mail us</ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:portingajde"
+ xreflabel="Q:Can I port AJDE support to my development environment?">
+ <para>Can I port AJDE support to my development environment?</para>
+ </question>
+ <answer>
+ <para>Yes. The core AJDE API is extensible and the source code is
+ available for download. Start by studying the sources
+ for the existing IDE support.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="notes" xreflabel="Programming notes and tips">
+ <title>Programming notes and tips</title>
+ <qandaentry>
+ <question id="q:methodsignatures"
+ xreflabel="Q:Is it possible to change methods by introducing keywords, adding parameters, or changing the throws clause?">
+ <para>Is it possible to change methods by introducing keywords (like
+ <literal>synchronized</literal>), adding parameters,
+ or changing the "throws" clause?
+ </para>
+ </question>
+ <answer>
+ <para>AspectJ does not enable you to change the signature of a method,
+ but you can (by express declaration) work around some
+ limits imposed by the signature. You can convert a checked exception to
+ unchecked using <literal>declare soft</literal>, privileged aspects
+ have access to private methods, and you can use a percflow aspect to
+ ferry additional state to a callee without changing intervening
+ signatures. For more details, see
+ <ulink url="progguide/index.html">The AspectJ Programming Guide</ulink>.
+ In the case of <literal>synchronized</literal>,
+ we have what we consider a better solution that uses
+ around advice instead of introduction. This solution is described
+ in
+ <ulink url="http://aspectj.org/pipermail/users/2000/000534.html">
+ this thread
+ </ulink> on the AspectJ users list, with some
+ <ulink url="http://aspectj.org/pipermail/users/2000/000536.html">
+ additional comments
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:seeingjoinpoints"
+ xreflabel="Q:I don't understand what join points exist. How can I see them?">
+ <para>
+ I don't understand what join points exist. How can I see them?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Try using an aspect posted to the user's list called
+ <ulink url="http://aspectj.org/pipermail/users/2002/001883.html">
+ TraceJoinPoints.java
+ </ulink>.
+ For example, you can start logging at a particular method call and
+ see what join points occur after the call and before it returns.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:comparecallandexecution"
+ xreflabel="Q:What is the difference between call and execution join points?">
+ <para>
+ What is the difference between call and execution join points?
+ </para>
+ </question>
+ <answer>
+ <para>Consider method execution in Java as (1) the initial call from
+ this object to some method on the target object with a
+ particular signature; and (2) the execution of the actual code
+ in the particular method dispatched in the target object.
+ The call join point starts with the initial call and ends
+ when control returns to the call (by return or perhaps
+ thrown exception). The execution join point starts with
+ the method body and ends when the body completes (again
+ by return or throwing an exception), so the execution join
+ point always happens within the bounds of the corresponding
+ call join point. You can see this if you use the
+ join-point tracing aspect in
+ <ulink url="http://aspectj.org/pipermail/users/2002/001883.html">
+ TraceJoinPoints.java
+ </ulink>.
+ as described above.
+ </para>
+ <para>As you would expect, the context differs
+ in advice on pointcuts picking out execution and call join
+ points; for call, <literal>this</literal> refers to the caller, whereas
+ for execution <literal>this</literal> refers to the called
+ (executing) object.
+ </para>
+ <para>
+ There are some subtle interactions with other AspectJ semantics.
+ First, the meaning of the signature in the
+ <literal>execution()</literal> and <literal>call()</literal>
+ pointcut designators (PCD's) differ: the call type depends upon
+ the type of the reference making the call, while the execution
+ type depends on the enclosing class.
+ Second, you may choose one over another if you cannot bring all
+ your sources within the code the compiler controls
+ (described in the <ulink url="progguide/apb.html">appendix</ulink>
+ to the <literal>Programming Guide</literal>).
+ For example, to trace calls into a
+ method from classes which are outside the code the compiler controls
+ at compile time, then using <literal>execution()</literal> will work
+ while using <literal>call()</literal>may not. Finally, since
+ <literal>super</literal> invocations are not considered method calls,
+ to trace <literal>super.foo()</literal> would require using
+ <literal>execution</literal>.
+ </para>
+ <para>
+ In most cases you should use the <literal>call()</literal>
+ pointcut designator unless you have a good reason to use
+ <literal>execution()</literal>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:comparecflowandcflowbelow"
+ xreflabel="Q:What is the difference between cflow and cflowbelow?">
+ <para>
+ What is the difference between cflow and cflowbelow?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Both pick out all the join points in the control flow of
+ the specified join points.
+ They differ only in that the <literal>cflowbelow()</literal>
+ pointcut designator does not pick out the join points
+ specified, while <literal>cflow()</literal> does.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compareccallandexecution"
+ xreflabel="Q:What is the difference between call and execution?">
+ <para>
+ What is the difference between call and execution?
+ </para>
+ </question>
+ <answer>
+ <para>
+ There are two interesting times when a constructor or method is
+ run. Those times are when it is called, and when it actually
+ executes.
+ </para>
+ <para>
+ The main difference is that a call join point happens outside of
+ the object (for non-static methods) or class (for static methods
+ and constructors), and that an execution join point happens inside
+ the object or class. This means that the <literal>within</literal>
+ and <literal>withincode</literal> pointcuts pick them out
+ differently: A call join point is picked out within the caller,
+ while an execution join point is picked
+ out where it is actually defined.
+ </para>
+ <para>
+ A call join point is the ``outermost'' join point for a particular
+ call. Once a call join point proceeds, then a number of different
+ things happen. For non-static methods, for example, method
+ dispatch happens, which will cause one method execution join point
+ -- perhaps more, if there are super calls. For constructors, the
+ super constructor is called, and fields are initialized, and then
+ various constructor execution join points will occur.
+ </para>
+ <para>
+ A call join point matches only the ``external'' calls of a method
+ or constructor, based on a signature, and it does not pick out
+ calls made with <literal>super</literal>, or
+ <literal>this</literal> constructor calls.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:recursiveentrypoints"
+ xreflabel="Q:How do I say that I want the topmost entrypoint in a recursive call?">
+ <para>How do I say that I want the topmost entrypoint in a
+ recursive call? How about the most-recent prior entrypoint?
+ </para>
+ </question>
+ <answer>
+ <para>This is best seen by way of example.
+ Given a recursive call to <literal>int factorial(int)</literal>
+ you can print the arguments for
+ (a) the current and most-recent recursive call
+ or (b) the current and original recursive call:
+ </para>
+ <programlisting>
+aspect LogFactorial {
+ pointcut f(int i) : call(int factorial(int)) &amp;&amp; args(i);
+
+ // most-recent
+ before(int i, final int j) : f(i) &amp;&amp; cflowbelow(f(j)) {
+ System.err.println(i + "-" + j);
+ }
+
+ // original
+ before(int i, final int j) : f(i)
+ &amp;&amp; cflowbelow(cflow(f(j)) &amp;&amp; !cflowbelow(f(int))) {
+ System.err.println(i + "@" + j);
+ }
+}
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:initializationjoinpoints"
+ xreflabel="Q:What is the difference between constructor call, constructor execution, initialization, and static initialization join points?">
+ <para>What is the difference between constructor call,
+ constructor execution, initialization, and static
+ initialization join points?
+ </para>
+ </question>
+ <answer>
+ <para>Static initialization pertains to initialization of
+ a class or interface type. Constructor call and execution
+ are akin to method call, and initialization generalizes this and
+ picks out the first constructor called.
+ </para>
+ <para>Their relations are best
+ demonstrated by tracing the join points. Below is the class
+ Test which implements an interface and extends a class
+ along with a trace of the join points below and including
+ the constructor call obtained using
+ <literal>TraceJointPoints.java</literal> (linked above).
+ </para>
+ <programlisting>
+ <![CDATA[
+public class Init {
+ public static void main (String[] args) {
+ new Test();
+ end();
+ }
+ static void end() {}
+}
+class Super {}
+interface I {}
+class Test extends Super implements I {
+ Test() {}
+}
+
+ <constructor-call sig="Test()" >
+ <staticinitialization sig="Super._init_" />
+ <staticinitialization sig="Test._init_" />
+ <initialization sig="Super()" >
+ <instanceinitializer-execution sig="Super._init_" />
+ <constructor-execution sig="Super()" />
+ </initialization>
+ <initialization sig="I()" >
+ <instanceinitializer-execution sig="I._init_" />
+ <constructor-execution sig="I()" />
+ </initialization>
+ <initialization sig="Test()" >
+ <instanceinitializer-execution sig="Test._init_" />
+ <constructor-execution sig="Test()" />
+ </initialization>
+ </constructor-call>
+]]>
+ </programlisting>
+ <para>
+ Ordinarily, using a <literal>call</literal> pointcut designator
+ is best because the call join point surrounds the others, but in
+ the case of constructors there is no target object for
+ the call (because it has not been constructed yet), so you
+ might prefer to use the <literal>initialization</literal>
+ pointcut designator.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:andingpointcuts"
+ xreflabel="Q:I want advice to run at two pointcuts, but it doesn't run at all.">
+ <para>
+ I want advice to run at two pointcuts, but it doesn't run at all. What gives?
+ </para>
+ </question>
+ <answer>
+ <para>
+ This reflects both a conceptual error and a programming mistake.
+ Most likely you want to do something like "run the advice for all
+ public and private calls," and the code looks something like this:
+ </para>
+ <programlisting>
+ within(com.xerox.printing..*) &amp;&amp; call(public * *(..)) &amp;&amp; call(private * *(..))
+ </programlisting>
+ <para>
+ A pointcut picks out join points; it is evaluated at each join point.
+ The expression above would never pick out any call join point,
+ because no method signature has both public and private access.
+ In a pointcut, <literal>pc1() &amp;&amp; pc2()</literal> means both
+ must be true at a given join point for advice to run at that join point.
+ The correct pointcut would use <literal>||</literal> as follows:
+ </para>
+ <programlisting>
+ within(com.xerox.printing..*) &amp;&amp; (call(public * *(..)) || call(private * *(..)))
+ </programlisting>
+ <para>
+ Then the advice will run at the join point.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:staticfieldreferences"
+ xreflabel="Q:How do I refer to a static field when my advice crosscuts multiple classes?">
+ <para>
+ How do I refer to a static field when my advice crosscuts multiple classes?
+ </para>
+ </question>
+ <answer>
+ <para>There is no way in advice to refer to the type of the
+ code executing in a static context except by specification.
+ This makes it impossible to refer to static members using
+ runtime information.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:interfacesastypepatterns"
+ xreflabel="Q:How can I reuse a type pattern?">
+ <para>I would like to reuse a type pattern, e.g., to
+ write advice that is limited to a certain set of classes.
+ Do I have to retype it each time?
+ </para>
+ </question>
+ <answer>
+ <para>No. You can declare that all the types implement
+ an interface you define, and then use the interface type in
+ your program. For example:
+ </para>
+ <programlisting>
+/**
+ * Example of using an interface to represent a type pattern.
+ * sub-aspects use declare parents to add to traced types, e.g.,
+ * declare parents: com.mycompany.whatever..* implements Marked;
+ */
+abstract aspect MarkerExample {
+ /** marker interface for types that we want to trace */
+ interface Marked {}
+
+ /** calls to an instance of Marked not from an instance of Marked */
+ pointcut dynamicCallsIn(): call(* *(..)) &amp;&amp; target(Marked) &amp;&amp; !this(Marked);
+
+ /** calls to methods defined by a subtype of Marked
+ * that don't come from the body of a subtype of Marked
+ */
+ pointcut staticCallsIn(): call(* Marked+.*(..)) &amp;&amp; !within(Marked+);
+
+ /** print dynamic calls */
+ before(): dynamicCallsIn() { System.out.println("before " + thisJoinPoint); }
+}
+
+aspect MyMarker extends MarkerExample {
+ declare parents: com.mycompany.whatever..* implements Marked;
+}
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:exampleprograms"
+ xreflabel="Q:Where do I find example programs?">
+ <para>Where do I find example programs?</para>
+ </question>
+ <answer>
+ <para>Some examples are distributed in the documentation release,
+ and you can find other code in the discussions on the users list.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:aspectlibraries"
+ xreflabel="Q:Are aspect libraries available?">
+ <para>Are aspect libraries available?</para>
+ </question>
+ <answer>
+ <para>Some libraries are distributed in the release under the
+ examples folder in the distribution. If you develop a library and
+ want to make it available to other users, make sure to
+ <ulink
+ url="http://aspectj.org/servlets/AJSite?channel=supportAndBugs&amp;subChannel=askAQuestion">
+ contact us
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:serialversionuid"
+ xreflabel="Q:How does ajc interact with the serialVersionUID?">
+ <para>How does <literal>ajc</literal> interact with the
+ <literal>serialVersionUID</literal>?
+ </para>
+ </question>
+ <answer>
+ <para>The current version of <literal>ajc</literal> can change the
+ <varname>serialVersionUID</varname> of generated
+ <filename>.class</filename> files as a result of weaving in advice.
+ This is an important fact that developers using both aspects and
+ serialization should be aware of. It is likely that a future
+ version of the compiler will be better behaved regarding the
+ <varname>serialVersionUID</varname>.
+ </para>
+ <para>However, changes to the <literal>serialVersionUID</literal>
+ attribute are typically only important when using serialization for
+ the long-term persistence of objects. Using standard Java
+ serialization for long-term persistence has a number of drawbacks
+ and many developers already use alternative solutions. For one
+ possibly standard solution, see
+ <ulink url="http://jcp.org/jsr/detail/057.jsp">
+ Lon
+ g-Term Persistence for JavaBeans Specification
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:applets"
+ xreflabel="Q:How can I use AspectJ with applets?">
+ <para>How can I use AspectJ with applets?</para>
+ </question>
+ <answer>
+ <para>
+ Just include the aspectjrt.jar as a required archive.
+ For example, here is the HTML code for an HTML editor
+ applet that contains some debugging aspects:
+ </para>
+ <programlisting>
+ <![CDATA[
+<APPLET
+ CODE='com.company.swing.applets.EditorApplet'
+ WIDTH='700'
+ HEIGHT='525'>
+ <PARAM NAME="CODE" VALUE="com.company.swing.applets.EditorApplet" >
+ <PARAM NAME="ARCHIVE"
+ VALUE ="../company-applets.jar,../aspectjrt.jar,../xmlrpc-applet.jar" >
+ <PARAM NAME="type" VALUE="application/x-java-applet;version=1.4">
+ <PARAM NAME="scriptable" VALUE="false">
+</APPLET>
+]]>
+ </programlisting>
+ <para>
+ The above markup has worked reliably with the Java Plugin
+ (included in the JRE 1.4.x) in IE 6, Mozilla 1.1 (Win32),
+ and Mozilla 1.0.1 (Red Hat Linux 8.0).
+ The following link describes how to configure Mozilla/Netscape
+ 6.x/7.x to use the Java Plugin from a JRE/SDK installation:
+ <ulink url="http://java.sun.com/j2se/1.4.1/manual_install_linux.html">
+ http://java.sun.com/j2se/1.4.1/manual_install_linux.html</ulink>.
+ (Thanks to Chris Bartling for this answer.)
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:typeoblivious"
+ xreflabel="Q:How can I specify types for advice that captures primitives, void, etc.?">
+ <para>How can I specify types for advice that captures primitives, void, etc.?</para>
+ </question>
+ <answer>
+ <para>
+ In some cases, AspectJ allows conversion from values of primitive types to Object,
+ so that highly polymorphic advice may be written. This works if an advice parameter
+ or the return type for around is typed to Object. So:
+ </para>
+ <programlisting>
+class Test {
+ static int i;
+ public static void main(String[] args) {
+ i = 37;
+ }
+}
+
+aspect TraceSet {
+ before(Object val): set(* Test.*) &amp;&amp; args(val) {
+ System.err.println(val);
+ System.err.println(val.class);
+ }
+}
+ </programlisting>
+ <para>
+ will print out
+ </para>
+ <programlisting>
+37
+java.lang.Integer
+ </programlisting>
+ <para>
+ For more information, see the Programming Guide
+ <ulink url="http://aspectj.org/doc/dist/progguide/apbs02.html">
+ semantics section "Context Exposure"
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="problems" xreflabel="Common Problems">
+ <title>Common Problems</title>
+ <qandaentry>
+ <question id="q:infiniterecursion"
+ xreflabel="Q:When I run, I get a StackOverflowError or no output.">
+ <para>When I run, I get a <literal>StackOverflowError</literal>
+ (or a long stack trace or no output whatsoever)
+ </para>
+ </question>
+ <answer>
+ <para>Most likely this is a case of infinite recursion,
+ where advice is advising itself. It presents as a
+ <literal>StackOverflowError</literal>
+ or silence as the VM exhausts itself in the recursion.
+ </para>
+ <para>Of course, infinite recursion is possible in Java:</para>
+ <programlisting>
+public class Main {
+ public static void main(String[] args) {
+ try {
+ main(args);
+ } finally {
+ main(args);
+ }
+ }
+}
+ </programlisting>
+ <para>If you compile and run this program, and it will fail silently, trying
+ to process the finally clause even after throwing the StackOverflowError.
+ </para>
+ <para>Here's a similar AspectJ program where the recursion is
+ not so obvious:
+ </para>
+ <programlisting>
+aspect A {
+ after(): call(* *(..)) { System.out.println("after " + thisJoinPoint); }
+}
+ </programlisting>
+ <para>This re-invokes itself because it advises any call.
+ It invokes itself even after an exception is thrown, since
+ <literal>after</literal> advice, like a finally clause, runs even
+ after exceptions are thrown. You can fix this by following two practices:
+ </para>
+ <para>
+ (1) Use <literal>after returning</literal> to advise normal completions
+ or <literal>after throwing</literal> to advise abrupt completions.
+ If you use <literal>after</literal> or <literal>after throwing</literal>,
+ write the advice with the same care you would a finally clause,
+ understanding that it may run after some failure.
+ </para>
+ <para>(2) Avoid writing advice that advises itself. One simple way to
+ do so is to exclude the code within the current aspect:
+ </para>
+ <programlisting>
+aspect A {
+ after() returning: !within(A) &amp;&amp; call(* *(..)) {
+ System.out.println("after " + thisJoinPoint);
+ }
+}
+ </programlisting>
+ <para>A better way is often to re-write the pointcut.
+ If the advice is advising itself accidentally, that's a sign that
+ the pointcut is not saying what you mean.
+ </para>
+ <programlisting>
+aspect A {
+ pointcut withinTargetClasses() : within(A+) || within(B+);
+ after() returning: withinTargetClasses() &amp;&amp; call(* *(..)) {
+ System.out.println("after " + thisJoinPoint);
+ }
+}
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:typelessdeclarations"
+ xreflabel="Q:I've declared a field on every class in my package; how do I use it in advice?">
+ <para>I've declared a field on every class in
+ my package; how do I use it in advice?
+ </para>
+ <programlisting>
+aspect A {
+ boolean com.xerox..*.dirtyFlag;
+ after (Object target) returning
+ : target(target) &amp;&amp; call(* com.xerox..*.set*(..)) {
+ target.dirtyFlag = true; // compile fails here
+ }
+}
+ </programlisting>
+ </question>
+ <answer>
+ <para>You need a type to refer to any member, field or method.
+ It's generally better to introduce onto an interface and
+ declare classes to implement the interface, which permits you
+ to use the interface type in advice formals.
+ </para>
+ <programlisting>
+aspect A {
+ interface TrackingSets {}
+ boolean TrackingSets.dirtyFlag;
+ declare parents : com.xerox..* implements TrackingSets;
+
+ after (TrackingSets target) returning
+ : target(target) &amp;&amp; call(* com.xerox..*.set*(..)) {
+ target.dirtyFlag = true;
+ }
+}
+ </programlisting>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:ajcoom"
+ xreflabel="Q:The AspectJ compiler aborts with an OutOfMemoryError when compiling many classes. How can I fix this?">
+ <para>The AspectJ compiler aborts with an OutOfMemoryError when
+ compiling many classes. How can I fix this?
+ </para>
+ </question>
+ <answer>
+ <para>The command <literal>ajc</literal> is actually a script that
+ launches a Java virtual machine with the correct classpath. You
+ should make a copy of this script, rename it, and then edit it.
+ Change the -Xmx option, size of memory allocation pool (heap). You
+ might try <literal>-Xmx128M</literal> or even
+ <literal>-Xmx256M</literal>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:ajcrecompile"
+ xreflabel="Q:ajc recompiles all files every time. How can I make it recompile only the files that have changed?">
+ <para>
+ <literal>ajc</literal> recompiles all files every time.
+ How can I make it recompile only the files that have changed?
+ </para>
+ </question>
+ <answer>
+ <para>
+ <literal>ajc</literal> 1.0 does not currently support incremental
+ compilation, but we are working on this for the 1.1 release.
+ </para>
+ <para>As a limited workaround, many build systems enable you to avoid
+ doing a compile if no sources have changed. (See, e.g., Ant's
+ "uptodate" task.)
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:ajcjvm"
+ xreflabel="Q:ajc is using the wrong JVM. How do I fix it?">
+ <para>
+ <literal>ajc</literal> is using the wrong JVM. How do I
+ fix it?
+ </para>
+ </question>
+ <answer>
+ <para>The easiest way to fix this is to re-install
+ <literal>ajc</literal> (using the same <literal>.class</literal> or
+ <literal>.exe</literal> file that you originally downloaded) and
+ this time make sure to tell it to use the desired JDK (typically
+ the JDK versions 1.2 or 1.3 from Sun).
+ </para>
+ <para>If you are familiar with DOS batch files or shell programming,
+ you could also fix this by simply editing the
+ <literal>bin\ajc.bat</literal> or <literal>bin/ajc</literal>
+ script.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:idebalkingataspects"
+ xreflabel="Q:My IDE is trying to parse AspectJ files which makes my project unusable. What can I do?">
+ <para>My IDE is trying to parse AspectJ files which makes my project unusable.
+ What can I do?
+ </para>
+ </question>
+ <answer>
+ <para>
+ When working with an unsupported IDE that objects to the syntax of
+ AspectJ source files (and, e.g., automatically gathers them
+ in a source tree as Java files based on the .java extension),
+ you can use the .aj extension for your AspectJ files.
+ The ajc compiler accepts both .java and .aj files, and you can
+ set up your build scripts to include the correct list of
+ source files. (You will have to find another editor for
+ editing AspectJ files; you can use the ajbrowser to view
+ edit your AspectJ files and navigate the crosscutting structure.)
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:idememory"
+ xreflabel="Q:I used to be able to compile my program, but now I run out of memory.">
+ <para>I used to be able to compile my program in my IDE, but when I
+ use AJDE, I run out of memory (or it goes really slow).
+ </para>
+ </question>
+ <answer>
+ <para>
+ The ajc compiler does more analysis than (e.g.,) javac,
+ and AJDE may in some IDE's hold a copy of the structure tree until the
+ next tree is available from the compile process. Both mean that you may
+ need extra memory to compile the same program. However, increasing
+ available memory to the point that you are swapping to disk can
+ slow the process considerably.
+ </para>
+ <para>
+ If you are having problems and would like to find the optimal memory
+ allocation, iteratively decrease the amount of memory available until
+ AJDE or ajc signals out-of-memory errors, and then increase that
+ amount by 5-10%.
+ </para>
+ <para>
+ To increase memory for the ajc compiler, see <xref linkend="q:ajcoom"/>.
+ For your IDE, do something similar or follow the provider's instructions.
+ For example, to increase memory in JBuilder, edit the
+ <literal>jbuilderX/bin/jbuilder.config</literal>
+ file to have an entry like:
+<programlisting>
+vmparam -Xmx384m
+</programlisting>
+ </para>
+ <para>
+ If it turns out that your project is too big to use with AJDE, your IDE
+ may nonetheless support external commands or Ant build processes, which
+ run outside the IDE memory space. For an Ant taskdef, see
+ <ulink url="http://aspectj.org/dl"/>. For a JBuilder Ant plugin, some
+ people have directed us to <ulink url="http://antrunner.sourceforge.net"/>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:stacktraces"
+ xreflabel="Q:My stack traces don't make sense. What gives?">
+ <para>
+ My stack traces don't make sense. What gives?
+ </para>
+ </question>
+ <answer>
+ <para>Unless you are using the <literal>ajdb</literal> debugger,
+ stack traces may
+ have synthetic methods in the stack, and the line numbers may
+ not track your source code. The
+ <ulink url="devguide/index.html">Development Environment Guide</ulink>.
+ discusses how to interpret stack at the end of the section
+ on the <literal>ajc</literal> compiler.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:advicenotrunning"
+ xreflabel="Q:My advice is not running (or running twice), and I don't know why.">
+ <para>
+ My advice is not running (or running twice), and I don't know why.
+ </para>
+ </question>
+ <answer>
+ <para>When advice is not running, it is probably a problem in the
+ pointcut. Sometimes users specify pointcuts that do not mean what they intend -
+ most often when they misspell a type name. Run the compiler in
+ <literal>-Xlint</literal> mode, which will flag some likely mistakes,
+ like the type name. If that does not work, use
+ <ulink url="http://aspectj.org/pipermail/users/2002/001883.html">
+ TraceJoinPoints.java
+ </ulink> to see if your join points are executing at all.
+ </para>
+ <para>When advice is running more than it should, it may be that your
+ pointcut picks out more join points than you intend.
+ If you are using IDE support, you should be able to trace back from
+ the pointcut or advice to the join points which can be statically
+ determined to be affected. To identify advised dynamic join points,
+ you can try using
+ <ulink url="http://aspectj.org/pipermail/users/2002/001883.html">
+ TraceJoinPoints.java
+ </ulink>, but often it is easier to update the advice to
+ print the source location of the join point.
+ This will show if the advice applies to code that you did
+ not consider.
+ </para>
+ <para>If you've done this and convinced yourself it's not working,
+ it may be a bug. See <xref linkend="q:bugreports"/>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:packagedeclares"
+ xreflabel="Q:I declared a member on a class with package access, but other classes in the package cannot see it.">
+ <para>
+ I declared a member on a class with package access, but other classes in the package cannot see it.
+ </para>
+ </question>
+ <answer>
+ <para>When declaring parents on other types from an aspect, package access only
+ applies to code the implementation controls. For AspectJ 1.0, that is the set of files
+ passed to the compiler. That means other classes not compiled with the aspect will not
+ be able to access the aspect-declared members even if they are in the same package.
+ The only way for classes outside the control of the implementation to access aspect-declared
+ members is to declare them public.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:cantfindjavac"
+ xreflabel="Q:ajc complains that it can't find javac. What's wrong?">
+ <para>
+ <literal>ajc</literal> complains that it can't find
+ <literal>javac</literal>. What's wrong?
+ </para>
+ </question>
+ <answer>
+ <para>
+ <literal>ajc</literal> does not try to locate
+ <literal>javac</literal> in your path: it uses the
+ <literal>javac</literal> classes directly. In JDK 1.2 and 1.3 these
+ classes are found in <literal>tools.jar</literal> (in the
+ <literal>lib</literal> directory of the JDK distribution), which
+ must be on your classpath to make
+ <literal>ajc</literal> work with <literal>javac</literal>.
+ Inspect the java command that launches ajc to make sure that
+ <literal>tools.jar</literal> is on the classpath for ajc;
+ the -classpath option only applies to the sources compiled.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:ajdocneeds13"
+ xreflabel="Q:I'm running under 1.4, but ajdoc asks for 1.3 (or throws IllegalAccessError for HtmlWriter.configuration)">
+ <para>
+ I'm running under 1.4, but <literal>ajdoc</literal> asks for 1.3
+ (or throws IllegalAccessError for HtmlWriter.configuration)
+ </para>
+ </question>
+ <answer>
+ <para>
+ The current implementation of <literal>ajdoc</literal> uses
+ specific javadoc classes in the J2SE 1.3 tools.jar.
+ We are working on addressing this limitation, but in the interim
+ it is best to run ajdoc under 1.3.
+ </para>
+ <para>
+ When running from the command-line scripts, edit the scripts directly
+ to put the 1.3 tools.jar first on the classpath. (The installer does
+ not know about this limitation of ajdoc.)
+ </para>
+ <para>
+ When running from Ant, users often have tools.jar in ${ant.classpath}
+ (to make javac, et al work). That makes it impossible to run the ajdoc
+ taskdef (which does not currently support forking), so you'll need to
+ run a separate ant process, either from the command-line or via Ant's
+ exec task (the Ant task will propagate the classpath).
+ If the wrong tools.jar is not on the ant classpath, then it should work
+ to put the 1.3 tools.jar in the taskdef classpath.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:compileunits"
+ xreflabel="Q:I set up different files to my compiles to change what the aspects see, but now I don't understand how the aspects are working?">
+ <para>I set up different files to my compiles to change what
+ the aspects see, but now I don't
+ understand how the aspects are working.
+ </para>
+ </question>
+ <answer>
+ <para>It is a bad practice to use the compilation unit
+ to control crosscutting. Aspects and pointcuts especially
+ should be written to specify crosscutting precisely.
+ Aspects will behave the same when you add files if
+ you initially included all files affected by your aspects.
+ If you use the compilation unit, then your code will behave
+ differently in AspectJ implementations that do not limit
+ themselves to specified files.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:readingpreprocessedcode"
+ xreflabel="Q:I'm reading the code generated by ajc in -preprocess mode, and it seems like it would not work.">
+ <para>I'm reading the code generated by <literal>ajc</literal>
+ in <literal>-preprocess</literal> mode, and it seems like it would not
+ work (or "like it works this way").
+ </para>
+ </question>
+ <answer>
+ <para>The generated code can be difficult for a human to read and
+ understand. The compiler uses implementation techniques which might
+ not be apparent. To determine if the code is behaving correctly, you
+ should write and run a program that attempts to provoke the error you
+ suspect. Similarly, you should not rely on invariants you infer from
+ the generated code (especially naming conventions for generated members).
+ Please rely only on the semantics stated in the appendix of the
+ AspectJ <ulink url="progguide/index.html">Programming Guide</ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:injection"
+ xreflabel="Q:I've heard AspectJ can generate or inject code into my code. Is this true?">
+ <para>I've heard AspectJ can generate or inject code into my code.
+ Is this true?
+ </para>
+ </question>
+ <answer>
+ <para>
+ This is a misconception spawned from the early implementation.
+ </para>
+ <para>
+ AspectJ does not "inject" or "generate" code. In AspectJ the
+ pointcut constructs allow the programmer to identify join points,
+ and the advice constructs define additional code to run at those
+ join points.
+ </para>
+ <para>
+ So the semantic model of advice is like the semantic model of a
+ method -- it says "when any of these things happen, do this".
+ </para>
+ <para>
+ People who worked with earlier versions of AspectJ, in which ajc
+ was very explicitly a pre-processor, sometimes thought of AspectJ
+ as injecting code. But that was an artifact of the implementation,
+ not the underlying language semantics.
+ </para>
+ <para>
+ This distinction is important for two reasons. One is that thinking
+ about it this way will make more sense at the implementation continues
+ to evolve towards load-time or runtime weaving. The other is that
+ it makes it much easier to understand the semantics of advice on
+ cflow pointcuts.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:currentbugs"
+ xreflabel="Q:What are the bugs now most affecting users?">
+ <para>What are the bugs now most affecting users?</para>
+ </question>
+ <answer>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <ulink url="http://aspectj.org/bugs/ajdoc?id=813">813</ulink>
+ - Ajdoc requires J2SE 1.3 tools.jar, not that of 1.2 or 1.4.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="help" xreflabel="Getting Help">
+ <title>Getting Help</title>
+ <qandaentry>
+ <question id="q:moreaboutaj"
+ xreflabel="Q:How do I find out more about AspectJ?">
+ <para>
+ How do I find out more about AspectJ?
+ </para>
+ </question>
+ <answer>
+ <para>Visit the AspectJ project web site:
+ <ulink url="http://aspectj.org">http://aspectj.org</ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:bugreports"
+ xreflabel="Q:How do I submit a bug report?">
+ <para>How do I submit a bug report?</para>
+ </question>
+ <answer>
+ <para>You can submit a bug using the web interface
+ <ulink url="http://aspectj.org/bugs">http://aspectj.org/bugs</ulink>
+ (preferred), or you may send email to
+ <ulink url="mailto:jitterbug@aspectj.org">jitterbug@aspectj.org</ulink> directly.
+ See also
+
+If it seems to be a bug in the compiler,
+ please include in the body of the email source code to reproduce the problem.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:comments"
+ xreflabel="Q:How do I submit comments and feature requests?">
+ <para>
+ How do I submit comments and feature requests?
+ </para>
+ </question>
+ <answer>
+ <para>You can email comments to all users at
+ <ulink url="mailto:users@aspectj.org">users@aspectj.org</ulink>,
+ email the AspectJ team at
+ <ulink url="mailto:support@aspectj.org">support@aspectj.org</ulink>.
+ You can view and submit bug reports and feature requests at
+ <ulink url="http://aspectj.org/bugs">http://aspectj.org/bugs</ulink>.
+ If you think you might simply be making a mistake, you might
+ email some source code to
+ <ulink url="mailto:users@aspectj.org">users@aspectj.org</ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:talktousers"
+ xreflabel="Q:How do I communicate with other AspectJ users?">
+ <para>
+ How do I communicate with other AspectJ users?
+ </para>
+ </question>
+ <answer>
+ <para>You can reach other AspectJ users by using the
+ aspectj-users mailing list. To subscribe to the list or view the
+ list archives go to the user community page:
+ <ulink url="http://aspectj.org/lists">
+ http://aspectj.org/lists
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:searchingsite"
+ xreflabel="Q:How can I search the email archives or the web site?">
+ <para>
+ How can I search the email archives or the web site?
+ </para>
+ </question>
+ <answer>
+ <para>
+ There is a search entry box on the left navigation bar of the web site,
+ but it is generally more effective to do a google search of the form,
+ <ulink url="http://www.google.com/search?q=site%3Aaspectj.org+%22abstract pointcuts%22">
+ http://www.google.com/search?q=site%3Aaspectj.org+%22abstract pointcuts%22
+ </ulink>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:writingbugsandemails"
+ xreflabel="Q:How should I write email queries?">
+ <para>
+ How should I write email queries?
+ </para>
+ </question>
+ <answer>
+ <orderedlist>
+ <listitem>
+ <para>
+ Here's the big picture of what I'm trying to do...
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Here's what I think it takes, in AspectJ terms
+ (concepts, syntax, and semantics) from the
+ <ulink url="progguide/index.html">Programming Guide</ulink>...
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Here's the AspectJ code I'm using, the output it
+ produces when run, and what I expect...
+ </para>
+ </listitem>
+ </orderedlist>
+ <para>
+ The big picture helps others redirect you to other approaches.
+ Using AspectJ terms helps others correct mistakes in thinking
+ about the problem (the most common being to confuse join points
+ and pointcuts).
+ The code is key to clarifying your question and getting a good
+ response. On the mail list, someone can reply by fixing your
+ code. In bugs, the developers can reproduce the problem immediately
+ and start analyzing the fix.
+ </para>
+ <para>
+ For the mail lists, we try to follow the conventions for open-source
+ discussions that help avoid "the tragedy of the commons."
+ For example conventions, see
+ <ulink url="http://jakarta.apache.org/site/mail.html">
+ http://jakarta.apache.org/site/mail.html
+ </ulink> and
+ <ulink url="http://www.tuxedo.org/%7Eesr/faqs/smart-questions.html">
+ http://www.tuxedo.org/%7Eesr/faqs/smart-questions.html
+ </ulink>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:idebugs"
+ xreflabel="Q:How do I write bugs for the IDE support?">
+ <para>
+ How do I write bugs for IDE support?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Bugs appearing in the IDE's may apply to the affected IDE
+ or to the compiler. Compiler stack traces in IDE message windows
+ are prefixed "Internal Compiler Error" and should be written up
+ as compiler bugs. If you are unsure, try redoing the compile
+ from the command line.
+ </para>
+ <para>
+ Bug reports for the Eclipse support go to the Eclipse
+ <ulink url="http://bugs.eclipse.org/bugs/enter_bug.cgi?product=AJDT">
+ bugzilla
+ </ulink> database.
+ Bug reports on other IDE support should have version
+ information for both Java and the IDE, and
+ (most importantly) clear steps for reproducing the bug.
+ You may submit the bugs via the web form
+ (<ulink url="http://aspectj.org/bugs">http://aspectj.org/bugs</ulink>)
+ or via email
+ (<ulink url="mailto:jitterbug@aspectj.org">jitterbug@aspectj.org</ulink>).
+ </para>
+ <para>
+ One of the benefits of open-source is that you can
+ find and fix the bug for yourself; when you submit
+ the fix back to us, we can validate the fix for you
+ and incorporate it into the next release. Email
+ <ulink url="mailto:support@aspectj.org">support@aspectj.org</ulink>
+ for instructions on submitting a patch.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:ajcbugs"
+ xreflabel="Q:How do I write bugs for the AspectJ compiler?">
+ <para>
+ How do I write bugs for the AspectJ compiler?
+ </para>
+ </question>
+ <answer>
+ <para>
+ The best compiler bug report is a reproducible test case,
+ standalone code that demonstrates the problem.
+ Sometimes with aspects, a test case requires several
+ files, if not some way to capture the behavior.
+ Here's how we recommend submitting test cases:
+ <orderedlist>
+ <listitem>
+ <para>
+ Write the test case so that when the compiler bug
+ is fixed, the test completes normally without output
+ (e.g., expected compiler errors are issued,
+ or classes produced run correctly). This usually
+ means writing one or more source files.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ In the bug report, briefly summarize the bug.
+ If it is not obvious, be sure to specify
+ the expected output/behavior (e.g., compiler error on line 32)
+ and, if the compile should complete, the main class to run.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ At the end of the report, append each source file,
+ separated with a line and the file name.
+ (Include all sources, and do not send attachments.)
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ Submit the bugs via the web form
+ (<ulink url="http://aspectj.org/bugs">http://aspectj.org/bugs</ulink>)
+ or via email
+ (<ulink url="mailto:jitterbug@aspectj.org">jitterbug@aspectj.org</ulink>).
+ </para>
+ </listitem>
+ </orderedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:teachingmaterials"
+ xreflabel="Q:Can you recommend reading or teaching material for AspectJ?">
+ <para>
+ Can you recommend reading or teaching material for AspectJ?
+ </para>
+ </question>
+ <answer>
+ <para>The documentation available on this site is a primary source of
+ material on AspectJ:
+ <informaltable frame="none">
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry valign="top">
+ <ulink url="http://aspectj.org/doc/papersAndSlides">
+ Selected AspectJ Papers and Presentations
+ </ulink>
+ </entry>
+ <entry>Papers presented at various conferences; tutorial
+ slide presentations.
+ </entry>
+ </row>
+ <row>
+ <entry valign="top">
+ <ulink url="http://aspectj.org/documentation/papersAndSlides/ECOOP1997-AOP.pdf">
+ Aspect-Oriented Programming
+ </ulink>
+ </entry>
+ <entry valign="top">
+ The seminal AOP/AspectJ paper
+ </entry>
+ </row>
+ <row>
+ <entry valign="top">
+ <ulink url="progguide/index.html">
+ The AspectJ Programming Guide
+ </ulink>
+ </entry>
+ <entry valign="top">A practical guide for programmers.
+ Includes a number of examples, some quite
+ sophisticated.
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <ulink url="tutorial.pdf">The AspectJ Tutorial</ulink>
+ </entry>
+ <entry>Slides from a day-long tutorial presentation on
+ AspectJ.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:consulting"
+ xreflabel="Q:Where can our group get consulting and support?">
+ <para>
+ Where can our group get consulting and support?
+ </para>
+ </question>
+ <answer>
+ <para>Beyond what's available on the aspectj.org web site,
+ the AspectJ team does a limited amount of consulting
+ and support for qualified groups. For more information,
+ see <xref linkend="q:support"/>.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:faqchanges"
+ xreflabel="Q:What has changed since the last FAQ version?">
+ <para>
+ What has changed since the last FAQ version?
+ </para>
+ </question>
+ <answer>
+ <para>
+ Entries changed since the earlier September 13 version:
+ <itemizedlist>
+ <listitem><para><xref linkend="q:ajdocneeds13"/></para></listitem>
+ <listitem><para><xref linkend="q:idebugs"/></para></listitem>
+ <listitem><para><xref linkend="q:ajcbugs"/></para></listitem>
+ <listitem><para><xref linkend="q:searchingsite"/></para></listitem>
+ <listitem><para><xref linkend="q:bytecodeweaving"/></para></listitem>
+ <listitem><para><xref linkend="q:differences"/></para></listitem>
+ <listitem><para><xref linkend="q:schedule"/></para></listitem>
+ <listitem><para><xref linkend="q:aopinjava"/></para></listitem>
+ <listitem><para><xref linkend="q:aspectjandj2ee"/></para></listitem>
+ <listitem><para><xref linkend="q:applets"/></para></listitem>
+ <listitem><para><xref linkend="q:packagedeclares"/></para></listitem>
+ <listitem><para><xref linkend="q:writingbugsandemails"/></para></listitem>
+ <listitem><para><xref linkend="q:andingpointcuts"/></para></listitem>
+ <listitem><para><xref linkend="q:idesupportplans"/></para></listitem>
+ <listitem><para><xref linkend="q:opensource"/></para></listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ <qandadiv id="project" xreflabel="About the AspectJ Project">
+ <title>About the AspectJ Project</title>
+ <qandaentry>
+ <question id="q:opensource"
+ xreflabel="Q:What does the fact that AspectJ is an Open Source Project mean to me?">
+ <para>What does the fact that AspectJ is an Open Source
+ Project mean to me?
+ </para>
+ </question>
+ <answer>
+ <para>Open source protects your interest in a correct, long-lived,
+ up-to-date, and widely-accepted implementation of AspectJ.
+ <itemizedlist>
+ <listitem>
+ <para>With the source code, you control your own destiny
+ in perpetuity. You can continue to use the implementation
+ and update it as necessary to fix bugs and add things you need.
+ </para>
+ </listitem>
+ <listitem>
+ <para>Because the code is available to all, anyone can find
+ and fix bugs. There is no need to hope for it to be fixed
+ in the next product release. Those who encounter the bugs
+ are motivated to fix them, and there are more eyeballs on
+ the code than in closed-source, so the quality tends to be high.
+ This can be particularly true for the AspectJ community,
+ which tends to be highly skilled.
+ </para>
+ </listitem>
+ <listitem>
+ <para>The same is true of new features or behavior, so the
+ implementation should be up-to-date. This is important as
+ the field of AOP develops, to capture the latest solutions.
+ </para>
+ </listitem>
+ <listitem>
+ <para>For a programming language which forms the basis of
+ an entire solution stack, open source facilitates the kind
+ of adoption -- tool integrations and significant projects --
+ that develop and prove the technology for wider adoption. This
+ limits delays caused by waiting for the completion of standards
+ process or promulgation by industry leaders, and also provides
+ the proofs necessary for such adoption.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:standardization"
+ xreflabel="Q:What are your plans to make AspectJ a general feature of Java supported by Sun and the other key-players in the Java Industry?">
+ <para>What are your plans to make AspectJ a general feature
+ of Java supported by Sun and the other key players in the Java
+ Industry?
+ </para>
+ </question>
+ <answer>
+ <para>Although we are committed to making AspectJ available to a wide
+ range of users, it is too early to decide on a strategy. Some
+ options include continuing AspectJ as a stand-alone product,
+ integrating it into IDEs, or possibly incorporating it into
+ standard Java with Sun's blessing.
+ </para>
+ <para>We currently focus on developing for the 1.1 implementation
+ which improves AspectJ in key areas: rapid
+ incremental compilation, bytecode weaving, and IDE integration.
+ </para>
+ <para>Through all of this our goal is to make AspectJ integrate as
+ seamlessly as possible with the Java programming language. The
+ AspectJ language design is becoming more integrated, the compiler
+ is becoming faster and more integrated, the IDE extensions are
+ becoming more integrated. All of this is designed to help users
+ really use AspectJ and give us feedback on it.
+ </para>
+ <para>As the system is improved and we work more closely
+ with users, we will be in good position to explore the best path
+ for AspectJ in the long term.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:bytecodeweaving"
+ xreflabel="Q:When will AspectJ work from class files? When will it work at class-loading time?">
+ <para>When will AspectJ work from class files?
+ When will it work at class-loading time?
+ </para>
+ </question>
+ <answer>
+ <para>Bytecode weaving is scheduled for AspectJ 1.1. We believe it
+ will work as described in an email to the users list by Jim Hugugin:
+ </para>
+ <para>
+ The AspectJ language was designed to support weaving at many different times:
+ compile, load, or even run-time in the JVM. Weaving into bytecodes at both
+ compile and load-time will definitely be provided in a future release. This
+ will allow weaving at compile-time into libraries for which source code is
+ not available. It will also support aspect-aware class loaders that can
+ perform weaving at load time on arbitrary classes. One advantage of a
+ language like AspectJ, rather than an explicit meta-tool like jiapi, is
+ that it separates the specification of a crosscutting concern from any
+ particular implementation strategy for weaving.
+ </para>
+ <para>
+ ...AspectJ provides a language that can cleanly
+ capture crosscutting concerns while preserving the static type checking,
+ modularity, and composability of Java.
+ </para>
+ <para>If you have an application for using aspects and bytecode,
+ please let the AspectJ team know of your requirements.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:differences"
+ xreflabel="Q:What are the differences between the current and previously released versions of AspectJ?">
+ <para>What are the differences between the current and
+ previously released versions of AspectJ?
+ </para>
+ </question>
+ <answer>
+ <para>The AspectJ team aims to keep the implementation up-to-date
+ and bug-free, but to limit language changes to those that
+ are carefully considered, compelling, and backwards-compatible,
+ and to deliver those language changes only in significant releases (1.0, 1.1).
+ </para>
+ <table>
+ <title></title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry align="left">Version</entry>
+ <entry align="left">Description</entry>
+ </row>
+ <row>
+ <entry>AspectJ 1.0</entry>
+ <entry>Many language changes, fixes, cleanup and
+ clarifications, some significant.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.8</entry>
+ <entry>More cleanup of the syntax and semantics.</entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.7</entry>
+ <entry>Clean up of the semantics, 0.7 beta 4 is the first
+ open source release.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.6</entry>
+ <entry>Advice and crosscuts get explicit type signatures
+ which describe the values that are available to advice at a
+ crosscut.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.5</entry>
+ <entry>Improved tool support: better Emacs environment
+ support and <literal>ajdoc</literal> to parallel
+ <literal>javadoc</literal>. around advice is added, and the
+ <literal>aspect</literal> keyword is removed and replaced
+ by the Java keyword class.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.4</entry>
+ <entry>Clear separation of crosscuts and crosscut actions
+ makes it possible to define extensible library
+ aspects.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.3</entry>
+ <entry>First all Java implementation, also includes many
+ small language improvements.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.2</entry>
+ <entry>General-purpose support for crosscutting. Users could
+ program any kind of aspects, not just coordination. This
+ release dropped COOL.
+ </entry>
+ </row>
+ <row>
+ <entry>AspectJ 0.1</entry>
+ <entry>A single domain-specific aspect language, called COOL,
+ for programming coordination in multi-threaded
+ programs.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para> More detailed comments are available in the
+ <literal>doc/changes.html</literal> file in the
+ distribution.
+ </para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question id="q:schedule"
+ xreflabel="Q:What is the AspectJ development schedule?">
+ <para>
+ What is the AspectJ development schedule?
+ </para>
+ </question>
+ <answer>
+ <table>
+ <title>The AspectJ Development Schedule</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry align="left">Version</entry>
+ <entry align="left">Description</entry>
+ </row>
+ <row>
+ <entry valign="top" align="center">1.0</entry>
+ <entry>Final syntax and semantic changes. Standalone structure
+ browser. Complete documentation.
+ </entry>
+ </row>
+ <row>
+ <entry valign="top" align="center">1.1</entry>
+ <entry>Faster incremental compilation, bytecode weaving,
+ and a small number of language changes.</entry>
+ </row>
+ <row>
+ <entry valign="top" align="center">2.0</entry>
+ <entry>New, dynamic crosscuts (bytecode-only)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </answer>
+ </qandaentry>
+ </qandadiv>
+ </qandaset>
+ <para>AspectJ is a registered trademark of Palo Alto Research Center, Incorporated (PARC).
+ Java and all Java-based marks are trademarks or registered trademarks of
+ Sun Microsystems, Inc. in the United States and other countries. All other
+ trademarks are the property of their respective owners.
+ </para>
+</article>
+<!--
+Local variables:
+compile-command: "java com.icl.saxon.StyleSheet -o faq.html faq.xml /usr/local/docbook/docbook-xsl-1.44/html/docbook.xsl"
+fill-column: 79
+sgml-local-ecat-files: faq.ced
+End:
+-->
diff --git a/docs/install/finish.html b/docs/install/finish.html
new file mode 100644
index 000000000..ef1bef64e
--- /dev/null
+++ b/docs/install/finish.html
@@ -0,0 +1,20 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>New Page 1</title>
+</head>
+
+<body>
+
+<p>The automatic installation process is complete.</p>
+
+<p>See <b><code>${installer.output.readme}</code></b> for more information about
+the contents of this package.</p>
+
+</body>
+
+</html>
diff --git a/docs/install/install-finish.html b/docs/install/install-finish.html
new file mode 100644
index 000000000..811f11400
--- /dev/null
+++ b/docs/install/install-finish.html
@@ -0,0 +1,20 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>New Page 1</title>
+</head>
+
+<body>
+
+<p>&nbsp;</p>
+
+<p>The automatic installation process is complete.&nbsp; Press <b>Next </b>for
+some final instructions.</p>
+
+</body>
+
+</html>
diff --git a/docs/install/install-start.html b/docs/install/install-start.html
new file mode 100644
index 000000000..858ed8512
--- /dev/null
+++ b/docs/install/install-start.html
@@ -0,0 +1,21 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>New Page 1</title>
+</head>
+
+<body>
+
+<p>&nbsp;</p>
+
+<p>Now installing to ${installer.output.dir}.</p>
+
+<p>Press <b>Cancel</b> to interrupt the installation.</p>
+
+</body>
+
+</html>
diff --git a/docs/install/intro.html b/docs/install/intro.html
new file mode 100644
index 000000000..55de23fbf
--- /dev/null
+++ b/docs/install/intro.html
@@ -0,0 +1,24 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>New Page 1</title>
+</head>
+
+<body>
+
+<h2 align="center">Installer for AspectJ(TM) Documentation and Examples</h2>
+
+<p align="center">Version ${build.version.long} built on ${build.date}</p>
+<p>${copyright.allRights.from1998}</p>
+<p></p>
+
+<p>Press <b>Next</b> to continue. At any time you may press <b>Cancel</b>
+to exit the installation process.</p>
+
+</body>
+
+</html>
diff --git a/docs/install/location.html b/docs/install/location.html
new file mode 100644
index 000000000..5eb2c5a8c
--- /dev/null
+++ b/docs/install/location.html
@@ -0,0 +1,23 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Language" content="en-us">
+<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
+<meta name="ProgId" content="FrontPage.Editor.Document">
+<title>New Page 1</title>
+</head>
+
+<body>
+
+<p>&nbsp;</p>
+
+<p>Please select a directory into which to install the aspectj documentation and
+examples.&nbsp; If you've already installed the compiler and core tools, we
+recommend that you install the documentation and examples to the same directory
+for convenience.</p>
+<p>Press <b>Install</b> to begin the installation process to this directory.</p>
+
+</body>
+
+</html>
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
diff --git a/docs/readme-docs-module.html b/docs/readme-docs-module.html
new file mode 100644
index 000000000..0bd11ae2b
--- /dev/null
+++ b/docs/readme-docs-module.html
@@ -0,0 +1,32 @@
+<html>
+<title>AspectJ docs</title>
+<body>
+<h1>AspectJ docs</h1>
+
+The AspectJ docs include native sources (html and word files)
+and XML DocBook files used to produce the FAQ and guides.
+The <a href="dist">dist</a> directory contains the native files
+as they are delivered with the distribution, and the
+docbook directories
+ <a href="faq">faq</a>,
+ <a href="progGuideDB">progGuideDB</a>, and
+ <a href="devGuideDB">devGuideDB</a>
+contain sources for the FAQ and the Programming and Development Guides,
+generated using the Ant <a href="build.xml">build.xml</a> script.
+
+<p>
+<u>Build</u>: The script uses a taskdefs defined in ../lib/build/build.jar
+to generate the installers, and others to do misc. text-conversion.
+Dependencies outside this directory:
+<ul>
+<li>.xml files refer to their docbook dtds using relative
+ path, for the moment ../../lib/docbook/...
+ <li>
+<li>When building docbook, uses ../lib/saxon libraries.
+ <li>
+<li>When building installer, using ../lib/build/build.jar
+ and the ../build/installer-resources.
+ <li>
+</ul>
+</body>
+</html>