|  | <?xml version="1.0" encoding="iso-8859-1"?> | 
|  | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | 
|  | "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | 
|  | <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | 
|  |  | 
|  | <!-- This file represents the Exercises for the hands-on AspectJ | 
|  | tutorial.  It is commonly checked into CVS with identifying | 
|  | information for the latest conference (such as presenters | 
|  | and publication information). | 
|  |  | 
|  | When you use it for your own purposes, don't forget to | 
|  | modify at the very least anything that says | 
|  | id="copyright" or class="presenter".  If you're in an A4 | 
|  | country, don't forget to modify the paper size. | 
|  |  | 
|  | The gif included at the end is somewhat fragile, | 
|  | so be careful with different paper sizes. | 
|  |  | 
|  | TODO: There is currently something weird about PDF generation | 
|  | from this:  If generated from a windows machine, it will | 
|  | generate mac-unfriendly PDF because of the requested windows | 
|  | font.  If the PDF is only used for immediate printing, | 
|  | that's fine, but if it's used for distribution, bad. | 
|  | --> | 
|  |  | 
|  | <head> | 
|  | <title>Hands-on Programming with AspectJ® — Exercises</title> | 
|  | <style type="text/css"> | 
|  | div.instruction { padding: 0.5em; border-width: 1px; border-style: solid } | 
|  | body { background-color: #FFF; margin: 2em } | 
|  | body { font-family: "Gill Sans MT", "Gill sans", "Trebuchet ms", Verdana, sans-serif; } | 
|  | .newpage { page-break-before: always } | 
|  | pre { margin-left: 1em; border-left-style: solid; border-width: 1px; padding-left: 1em;} | 
|  | h2 { margin-top: 4ex; } | 
|  | h3 { margin-top: 4ex; border-bottom-style: solid; border-width: 1px } | 
|  | .presenter { text-align: right } | 
|  | @page { | 
|  | size: 8.5in 11in; | 
|  | margin: 3in; | 
|  | marks: cross | 
|  | } | 
|  | @media print { | 
|  | body { font-size: 10pt } | 
|  | #copyright { | 
|  | font-family: "Times New Roman", "Times Roman", fixed; | 
|  | font-size: 8pt; | 
|  | display: normal; | 
|  | position: absolute; | 
|  | bottom: 1in; | 
|  | border-style: none | 
|  | } | 
|  | } | 
|  | @media screen { | 
|  | #copyright { display: none } | 
|  | } | 
|  | </style> | 
|  | </head> | 
|  |  | 
|  | <body> | 
|  |  | 
|  | <h1>Hands-on Programming with AspectJ<sup>®</sup></h1> | 
|  |  | 
|  | <div class="presenter">Matt Chapman</div> | 
|  | <div class="presenter">Matthew Webster</div> | 
|  | <div class="presenter">Mik Kersten</div> | 
|  | <div class="presenter">http://www.eclipse.org/aspectj</div> | 
|  | <div class="presenter">http://www.eclipse.org/ajdt</div> | 
|  |  | 
|  | <h2>Overview</h2> | 
|  |  | 
|  | <p> In this tutorial you will solve some basic programming | 
|  | tasks using AspectJ.  The tasks progress from writing | 
|  | non-functional, development-only aspects to writing aspects that | 
|  | augment a deployed program with crosscutting features.  This | 
|  | follows the same progression most users see in their own adoption | 
|  | of AspectJ. </p> | 
|  |  | 
|  | <p> Since this is a hands-on tutorial, you will be working with a | 
|  | live AspectJ distribution.  The example code we will be working | 
|  | with is a simple figure editor, along with JUnit tests for each | 
|  | exercise.  We will break up into groups of two to three people | 
|  | per computer to foster discussion within the group as well as | 
|  | with the presenters.  </p> | 
|  |  | 
|  | <p> If you have a laptop running a recent version of Windows, | 
|  | MacOS or Linux, feel free to bring it along.  We will provide CDs | 
|  | and other installation media for a standalone AspectJ system, | 
|  | including the figure editor code these exercises are based on and | 
|  | unit tests for the exercises.  If you don't have a laptop with | 
|  | you, don't worry about it.  </p> | 
|  |  | 
|  | <p> These notes consist of four sections of exercises, a quick | 
|  | reference to AspectJ syntax, and a UML diagram of a figure editor | 
|  | program. </p> | 
|  |  | 
|  | <div class="instruction"> If you receive these tutorial notes | 
|  | early, feel free to have a quick look, especially at the UML | 
|  | diagram and quick reference.  But you'll be cheating yourself if | 
|  | you try to do the exercises early; you'll learn a lot more by | 
|  | working through it in groups during the tutorial proper.  </div> | 
|  |  | 
|  | <!-- | 
|  | This space is used for a copyright that appears on the | 
|  | bottom of the _printed_ page.  It's suppressed when viewed on | 
|  | a computer screen by the stylesheet. | 
|  |  | 
|  | <div id="copyright"> | 
|  | Copyright is held by the author/owner(s). <br /> | 
|  | OOPSLA04, October 24-28, 2004, Vancouver, British Columbia, Canada <br /> | 
|  | 2004 ACM 04/0010 | 
|  | </div> | 
|  | --> | 
|  | <h3 class="newpage">AspectJ Development in Eclipse</h3> | 
|  |  | 
|  | <p>The AspectJ Development Tools (AJDT) plugins for Eclipse | 
|  | provide support for using the AspectJ compiler in the Eclipse environment. | 
|  | Different versions of AJDT are available to support both the latest | 
|  | release version of Eclipse, and the latest milestone build. | 
|  | As part of the tutorial we will be providing distributions of base | 
|  | eclipse, the AJDT plugins and the exercises. Should you wish to | 
|  | install the exercises into an existing configuration on your machine, | 
|  | you can download the exercises plugin via the following URL: | 
|  | </p> | 
|  |  | 
|  | <a href="http://eclipse.org/ajdt/EclipseCon2006/org.aspectj.tutorial.exercises_1.0.0.jar">http://eclipse.org/ajdt/EclipseCon2006/org.aspectj.tutorial.exercises_1.0.0.jar</a> | 
|  |  | 
|  | <p> | 
|  | Simply copy this JAR file to your eclipse/plugins folder. | 
|  | </p> | 
|  |  | 
|  | <h3>Installation</h3> | 
|  |  | 
|  | <p>The key components to have installed are:</p> | 
|  | <ul> | 
|  | <li>An Eclipse distribution - 3.1.2 or 3.2M5 | 
|  | <li>An AJDT distribution - 1.3 or 1.4.dev | 
|  | <li>An AspectJ Exercises plugin - 1.0.0 | 
|  | </ul> | 
|  |  | 
|  | <p>The best way to verify your installation is by attempting to | 
|  | create one of the 4 tutorial projects.  To do this, open File>New>Other... | 
|  | as shown here (or press the New button on the toolbar):</p> | 
|  | <p align="center"><img src="shots/FileNew.png"></p> | 
|  | <p>You should then see the following option:</p> | 
|  | <p align="center"><img src="shots/AJTutorials.png"></p> | 
|  | <p>If you do, congratulations, you are ready to go !!</p> | 
|  |  | 
|  | <!-- ============================== --> | 
|  |  | 
|  | <h2 class="newpage">1. Static Invariants</h2> | 
|  |  | 
|  | <p> The easiest way to get started with AspectJ is to use it to | 
|  | enforce static invariants, also known as compile time checks. These | 
|  | can be as simple as verifying a particular API is never called or as | 
|  | sophisticated as verifying your layered architecture is adhered to. | 
|  | </p> | 
|  | <p>The tutorial plugin includes four eclipse projects representing | 
|  | the four major parts of this tutorial.  Use the menus described in | 
|  | the previous two screenshots to create each exercise - create | 
|  | the first project now, <code>Exercise1</code>.</p> | 
|  |  | 
|  | <h3>1.a. Find old tracing</h3> | 
|  |  | 
|  | <div class="instruction"> <strong>Sample Exercise</strong>: The | 
|  | main point of this exercise is to make sure your configuration | 
|  | works.</div> | 
|  |  | 
|  | <p> <strong>Task:</strong> Signal an error for calls to | 
|  | <code>System.out.println</code>. | 
|  | </p> | 
|  |  | 
|  | <p> The way that we are all taught to print "hello world" from Java is | 
|  | to use <code>System.out.println()</code>, so that is what we typically | 
|  | use for one-off debugging traces.  It's a common mistake to leave | 
|  | these in your system far longer than is necessary.  Type in the aspect | 
|  | below to signal an error at compile time if this mistake is made. | 
|  | </p> | 
|  | <p>This is your first aspect, in order to create the necessary Eclipse | 
|  | resource into which you can type the answer, use the New Aspect Wizard. | 
|  | You can access this wizard in two ways:</p> | 
|  |  | 
|  | <p> | 
|  | 1. From the New Java Class drop-down on the toolbar: | 
|  | </p> | 
|  |  | 
|  | <p align="center"><img src="shots/NewAspectToolbarOption.png"></p> | 
|  |  | 
|  | <p> | 
|  | 2. From the File>New menu:</p> | 
|  | </p> | 
|  |  | 
|  | <p align="center"><img src="shots/NewAspectMenuOption.png"></p> | 
|  |  | 
|  |  | 
|  | <p>For this first aspect, fill it in as shown below:</p> | 
|  | <p align="center"><img src="shots/NewAspectWizard.png"></p> | 
|  | <p>After clicking <code>Finish</code> you should find yourself in the | 
|  | new aspect, change it to look like this following code</p> | 
|  |  | 
|  | <p> <strong>Answer:</strong> | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | package answers; | 
|  |  | 
|  | import figures.*; | 
|  |  | 
|  | aspect Answer { | 
|  | declare error | 
|  | : get(java.io.PrintStream System.out) && within(figures..*) | 
|  | : "illegal access to System.out"; | 
|  | } | 
|  | </pre> | 
|  |  | 
|  | <div class="instruction"><strong>Note: </strong>  For every task in this tutorial, you should work in the same | 
|  | Answer aspect that you create at the start of the exercise, comment out | 
|  | each previous answer as you move to the next task - if you don't then | 
|  | you may unexpectedly get some test failures.</p></div> | 
|  |  | 
|  | <p> After saving, a build will take place and you'll find one incorrect | 
|  | trace in <code>SlothfulPoint</code>:</p> | 
|  | <p align="center"><img src="shots/Answer1a.png"></p> | 
|  |  | 
|  | <p> Note that this answer does not say that the <em>call</em> to the | 
|  | <code>println()</code> method is incorrect, rather, that the field get | 
|  | of the <code>out</code> field is illegal.  This will also catch those | 
|  | users who bind System.out to a static field to save typing.  </p> | 
|  |  | 
|  | <p> After successfully finding the error, edit your | 
|  | program to remove the illegal tracing call.  </p> | 
|  |  | 
|  | <p> Make sure your program still passes the JUnit test | 
|  | <code>tests.CoreTest</code> (which it should also pass at the beginning of | 
|  | all exercises) before continuing.  Every exercise in this tutorial includes | 
|  | tests, each of which should be run individually.  To run a particular test, | 
|  | locate it in the <code>test-src</code> folder, then, right click the test | 
|  | and navigate to the <code>Run>JUnit Test</code> menu option as shown here:</p> | 
|  | <p align="center"><img src="shots/runningJUnitTests.png"></p> | 
|  |  | 
|  | <p>If it runs OK, you should get the trusty green bar:</p> | 
|  | <p align="center"><img src="shots/junitTestsPassing.png"></p> | 
|  |  | 
|  | <p>When it passes, you are ready to move on!</p> | 
|  |  | 
|  | <h3 class="newpage">1.b. Mandate setters</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Signal a warning for assignments outside | 
|  | of setter methods.  </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>set</code>, <code>withincode</code>, | 
|  | the <code>void set*(..)</code> pattern | 
|  | </p> | 
|  |  | 
|  | <p> One common coding convention is that no private field should | 
|  | be assigned to outside of setter methods.  Write an aspect to | 
|  | signal a warning at compile time for these illegal assignment | 
|  | expressions.  </p> | 
|  |  | 
|  | <p> This is going to look like | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | aspect Answer { | 
|  | declare warning: <em><pointcut here></em> : "bad field set"; | 
|  | } | 
|  | </pre> | 
|  |  | 
|  | <p> where the pointcut picks out join points of private field sets | 
|  | outside of setter methods.  "Outside", here, means that the code for | 
|  | the assignment is outside the <em>text</em> of the setter. | 
|  |  | 
|  |  | 
|  |  | 
|  | <p> Make sure your program still passes the JUnit test | 
|  | <code>tests.CoreTest</code> before continuing.  Make sure you get eleven | 
|  | warnings from this:</p> | 
|  | <p align="center"><img src="shots/1b_11warnings.png"></p> | 
|  |  | 
|  |  | 
|  | <p>Wait to fix them until the next exercise.  </p> | 
|  |  | 
|  | <h3>1.c. Refine setters mandate</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Allow assignmnents inside of constructors. | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> the <code>new(..)</code> pattern</p> | 
|  |  | 
|  | <p> Look at some of the warnings from the previous exercise.  Notice | 
|  | that a lot of them are from within constructors.  Actually, the common | 
|  | coding convention is that no private field should be assigned to outside of | 
|  | setter methods <em>or constructors</em>.  Modify your answer to signal | 
|  | an actual error at compile time (rather than just a warning) when such | 
|  | an illegal assignment expression exists.  </p> | 
|  |  | 
|  | <p>You'll want to add another <code>withincode</code> primitive | 
|  | pointcut to deal with the constructors. | 
|  | </p> | 
|  |  | 
|  | <p>After you specify your pointcut correctly, you'll still find that | 
|  | the convention is violated twice in the figures package.  You should see | 
|  | the following two errors:</p> | 
|  |  | 
|  | <pre> | 
|  | .\figures\Point.java:37 bad field set | 
|  | .\figures\Point.java:38 bad field set | 
|  | </pre> | 
|  |  | 
|  | <p>Rewrite these two occurrences so as not to violate | 
|  | the convention.  Make sure your program still passes the JUnit test | 
|  | <code>tests.CoreTest</code> before continuing.  </p> | 
|  |  | 
|  | <div class="instruction"> Congratulations, you've taken your | 
|  | first steps.  At this point, check the people to your left and | 
|  | right.  If they're stuck somewhere, see if you can help them. | 
|  | Try to resist moving on to the next section until we discuss | 
|  | solutions as a group. </div> | 
|  |  | 
|  | <!-- ============================== --> | 
|  |  | 
|  | <h2 class="newpage">2. Dynamic invariants</h2> | 
|  |  | 
|  | <p> The next step in AspectJ adoption is often to augment a test suite | 
|  | by including additional dynamic tests, sometimes called runtime checks. | 
|  | </p> | 
|  |  | 
|  | <div class="instruction"> Tutorial attendees typically progress | 
|  | at different speeds through these exercises.  Throughout this | 
|  | tutorial, if you finish early, see what the people around you are | 
|  | doing and if they need help.  Don't help them out of charity, | 
|  | help them out of naked self-interest—we promise you'll learn a | 
|  | lot about using AspectJ by explaining it. </div> | 
|  |  | 
|  | <h3>2.a. Check a simple precondition</h3> | 
|  |  | 
|  | <div class="instruction"> <strong>Sample Exercise</strong>: We've | 
|  | provided the answer to this exercise to get you started.  Feel | 
|  | free to think a bit, but don't get stuck on this one.  </div> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test2a</code>. | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>args</code>, <code>before</code> | 
|  | </p> | 
|  |  | 
|  | <p> Write an aspect to throw an <code>IllegalArgumentException</code> | 
|  | whenever an attempt is made to set one of <code>Point</code>'s | 
|  | <code>int</code> fields to a value that is less than zero.  </p> | 
|  |  | 
|  | <p> This should make the test case of <code>tests.Test2a</code> pass, | 
|  | which wouldn't without your aspect.  So before compiling in the | 
|  | aspect: | 
|  | </p> | 
|  |  | 
|  | <p align="center"><img src="shots/fail.png"></p> | 
|  |  | 
|  | <p> But after compiling in the aspect... | 
|  | </p> | 
|  |  | 
|  | <p align="center"><img src="shots/pass.png"></p> | 
|  |  | 
|  | <p> <strong>Answer:</strong> | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | package answers; | 
|  |  | 
|  | import figures.*; | 
|  |  | 
|  | aspect Answer { | 
|  | before(int newValue): set(int Point.*) && args(newValue) { | 
|  | if (newValue < 0) { | 
|  | throw new IllegalArgumentException("too small"); | 
|  | } | 
|  | } | 
|  | } | 
|  | </pre> | 
|  |  | 
|  | <h3>2.b. Check another precondition</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test2b</code>. </p> | 
|  |  | 
|  | <p> <strong>Tools: </strong> <code>call</code> | 
|  | </p> | 
|  |  | 
|  | <p> <code>Group</code> is a <code>FigureElement</code> class that | 
|  | encapsulates groups of other figure elements.  As such, only actual | 
|  | figure element objects should be added to <code>Group</code> objects. | 
|  | Write an aspect to throw an <code>IllegalArgumentException</code> | 
|  | whenever <code>Group.add()</code> is called with a <code>null</code> | 
|  | value. </p> | 
|  |  | 
|  | <p> Look at <code>tests/Test2b.java</code> to see exactly what we're | 
|  | testing for. </p> | 
|  |  | 
|  | <h3>2.c. Check yet another precondition</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test2c</code>. </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>target</code> | 
|  | </p> | 
|  |  | 
|  | <p> Another constraint on a well-formed group is that it should not | 
|  | contain itself as a member (though it may contain other groups). Write | 
|  | an aspect to throw an <code>IllegalArgumentException</code> whenever | 
|  | an attempt is made to call <code>Group.add()</code> on a | 
|  | <code>null</code> value, or on the group itself. </p> | 
|  |  | 
|  | <p> You will want to use a <code>target</code> pointcut to expose the | 
|  | <code>Group</code> object that is the target of the <code>add</code> | 
|  | call. | 
|  | </p> | 
|  |  | 
|  | <h3>2.d. Assure input</h3> | 
|  |  | 
|  | <p> <strong>Task: </strong> Pass <code>tests.Test2d</code>. | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools: </strong>  <code>around advice</code> | 
|  | </p> | 
|  |  | 
|  | <p> Instead of throwing an exception when one of <code>Point</code>'s | 
|  | <code>int</code> fields is set to a negative value, write an aspect | 
|  | to trim the value to zero.  You'll want to use <code>around</code> | 
|  | advice that exposes the new value of the field assignment with an | 
|  | <code>args</code> pointcut, and <code>proceed</code> with the trimmed | 
|  | value. </p> | 
|  |  | 
|  | <p> This is going to look something like | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | aspect Answer { | 
|  | void around(int val): <var><Pointcut></var> { | 
|  | <var><Do something with val></var> | 
|  | proceed(val); | 
|  | } | 
|  | } | 
|  | </pre> | 
|  |  | 
|  | <h3 class="newpage">2.e. Check a postcondition</h3> | 
|  |  | 
|  | <p> <strong>Task: </strong>  Pass <code>tests.Test2e</code> | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools: </strong>  <code>around advice</code> | 
|  | </p> | 
|  |  | 
|  | <p> A postcondition of a <code>Point</code>'s <code>move</code> | 
|  | operation is that the <code>Point</code>'s coordinates should change. | 
|  | If a call to move didn't actually move a point by the desired | 
|  | offset, then the point is in an illegal state and so an | 
|  | <code>IllegalStateException</code> should be thrown. | 
|  | </p> | 
|  |  | 
|  | <p> Note that because we're dealing with how the coordinates change | 
|  | during move, we need some way of getting access to the coordinates | 
|  | both before <em>and</em> after the move, in one piece of advice.  </p> | 
|  |  | 
|  | <h3>2.f. Check another postcondition</h3> | 
|  |  | 
|  | <p> <strong>Task: </strong>  Pass <code>tests.Test2f</code> | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> the <code> Rectangle(Rectangle)</code> | 
|  | constructor, the <code>Rectangle.translate(int, int)</code> method. | 
|  | </p> | 
|  |  | 
|  | <p> <code>FigureElement</code> objects have a <code>getBounds()</code> | 
|  | method that returns a <code>java.awt.Rectangle</code> representing the | 
|  | bounds of the object.  An important postcondition of the general | 
|  | <code>move</code> operation on a figure element is that the figure | 
|  | element's bounds rectangle should move by the same amount as the | 
|  | figure itself.  Write an aspect to check for this postcondition -- | 
|  | throw an <code>IllegalStateException</code> if it is violated.  </p> | 
|  |  | 
|  | <!-- ============================== --> | 
|  |  | 
|  | <h2 class="newpage">3. Tracing</h2> | 
|  |  | 
|  | <p> Tracing is one of the classic AspectJ applications, and is often | 
|  | the first where AspectJ is used on deployed code. | 
|  | </p> | 
|  |  | 
|  | <h3>3.a. Simple tracing</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test3a</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> | 
|  | <code>Log.write(String)</code>, | 
|  | <code>thisJoinPoint.toString()</code>, | 
|  | <code>execution</code>, | 
|  | <code>within</code> | 
|  | </p> | 
|  |  | 
|  | <p> Write an aspect to log the execution of all public methods | 
|  | in the figures package.  To do this, use the utility class | 
|  | <code>Log</code> (this is in the <code>support</code> package, so | 
|  | remember to import it into your answer aspect).  Write a message | 
|  | into the log with the static <code>write(String)</code> method.</p> | 
|  |  | 
|  | <h3>3.b. Exposing a value</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test3b</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>target</code> | 
|  | </p> | 
|  |  | 
|  | <p> AspectJ can expose the target object at a join point for tracing. | 
|  | In this exercise, you will print not only the join point information, | 
|  | but also the target object, with the form | 
|  | </p> | 
|  |  | 
|  | <pre> | 
|  | <em>thisJoinPointInfo</em> at <em>targetObject</em> | 
|  | </pre> | 
|  |  | 
|  |  | 
|  | <h3>3.c. More specialized logging</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test3c</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>args</code>. | 
|  | </p> | 
|  |  | 
|  | <p> Write an aspect to log whenever a <code>Point</code> is added to a | 
|  | group. The <code>args</code> pointcut allows you to select join points | 
|  | based on the type of a parameter to a method call. </p> | 
|  |  | 
|  | <p> Look at the test case to see the trace message we expect you | 
|  | to write in the log. | 
|  | </p> | 
|  |  | 
|  | <h3 class="newpage">3.d. Logging extended to checking an invariant</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test3d</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>inter-type field declaration</code> | 
|  | </p> | 
|  |  | 
|  | <p> Make sure that a <code>Point</code> is never added to more | 
|  | than one <code>Group</code>.  To do so, associate a boolean flag | 
|  | with each <code>Point</code> using an inter-type declaration, | 
|  | such as </p> | 
|  |  | 
|  | <pre> | 
|  | boolean Point.hasBeenAdded = false; | 
|  | </pre> | 
|  |  | 
|  | <p> Check and set this flag with the same kind of advice from your | 
|  | answer to problem (c).  Throw an <code>IllegalStateException</code> if | 
|  | the point has already been added. | 
|  | </p> | 
|  |  | 
|  | <h3>3.e. Better error messages for 3.d.</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test3e</code>.</p> | 
|  |  | 
|  | <p> Extend your solution to problem (d) by using the string | 
|  | representation of the Point's containing group as the <code>msg</code> | 
|  | part of the <code>IllegalStateException</code>. </p> | 
|  |  | 
|  | <!-- ============================== --> | 
|  |  | 
|  | <h2 class="newpage">4.  Caching</h2> | 
|  |  | 
|  | <p> Computation of the bounding box of <code>Group</code> objects | 
|  | needs to deal with all aggregate parts of the group, and this | 
|  | computation can be expensive.  In this section, we will explore | 
|  | various ways of reducing this expense. </p> | 
|  |  | 
|  | <div class="instruction"> <strong>Optional</strong>: In all of | 
|  | these exercises, you should only deal with points that are added | 
|  | directly to Groups, rather than those that are added "indirectly" | 
|  | through Lines and Boxes.  You should handle those points | 
|  | contained in Lines and Boxes only if time permits.  </div> | 
|  |  | 
|  | <h3>4.a. Make a constant override</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test4a</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>around</code>, | 
|  | <code>FigureElement.MAX_BOUNDS</code> | 
|  | </p> | 
|  |  | 
|  | <p> <code>Group</code>'s <code>getBounds()</code> method could be | 
|  | understood to be a conservative approximation of the bounding box of a | 
|  | group.  If that is true, then it would be a legal (and much faster) | 
|  | implementation of <code>getBounds()</code> to simply always return a | 
|  | rectangle consisting of the entire canvas.  The entire canvas is returned | 
|  | by the static field <code>FigureElement.MAX_BOUNDS</code>. | 
|  | </p> | 
|  |  | 
|  | <p> Write an aspect to implement this change.  You can override | 
|  | <code>Group</code>'s <code>getBounds()</code> method entirely with | 
|  | around advice intercepting the method. | 
|  | </p> | 
|  |  | 
|  | <h3>4.b. Make a constant cache</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test4b</code>. | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> inter-type field. | 
|  | </p> | 
|  |  | 
|  | <p> Instead of making the (very) conservative approximation of | 
|  | <code>getBounds()</code> from part (a), write an aspect instead that | 
|  | remembers the return value from the first time | 
|  | <code>getBounds()</code> has been called on a <code>Group</code>, and | 
|  | returns that first <code>Rectangle</code> for every subsequent | 
|  | call. </p> | 
|  |  | 
|  | <p> <em>Hint: You can use an inter-type declaration to keep some | 
|  | state for every <code>Group</code> object.</em> </p> | 
|  |  | 
|  |  | 
|  | <h3>4.c. Invalidate, part 1</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test4c</code>. | 
|  | </p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <code>before</code> | 
|  | </p> | 
|  |  | 
|  | <p> While caching in this way does save computation, it will lead to | 
|  | incorrect bounding boxes if a <code>Group</code> is ever moved. | 
|  | Change your aspect so that it invalidates the cache whenever the | 
|  | <code>move()</code> method of <code>Group</code> is called. | 
|  | </p> | 
|  |  | 
|  | <h3 class="newpage">4.d. Invalidate, part 2</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test4d</code>.</p> | 
|  |  | 
|  | <p> Of course, part (c) didn't really solve the problem.  What if a | 
|  | <code>Point</code> that is part of a <code>Group</code> moves? | 
|  | Whenever either of a Point's fields are set it should invalidate the | 
|  | caches of all enclosing groups.  Use your solution to problem 3c to | 
|  | modify your invalidation criteria in this way, but note that this is | 
|  | slightly different than the problem in 3c: Here you care about fields, | 
|  | where there you cared about method calls. </p> | 
|  |  | 
|  | <h3>4.e. Invalidate, part 3</h3> | 
|  |  | 
|  | <p> <strong>Task:</strong> Pass <code>tests.Test4e</code>.</p> | 
|  |  | 
|  | <p> <strong>Tools:</strong> <em>You're on you're own</em></p> | 
|  |  | 
|  | <p> Did you really do part (d) correctly?  Run the JUnit test | 
|  | <code>tests.Test4e</code> to see.  If you pass, congratulations, now | 
|  | go help other people.  Otherwise, you have fallen prey to our cruel | 
|  | trap: Remember that whenever a point moves it should invalidate the | 
|  | caches of <em>all</em> enclosing groups.  </p> | 
|  |  | 
|  | <div class="instruction"> | 
|  |  | 
|  | <p> Congratulations!  Not only have you learned about how to | 
|  | program in AspectJ, you have worked through exercises paralleling | 
|  | a common AspectJ adoption strategy.  You should be able to | 
|  | pick up AspectJ and use it to improve your own software's | 
|  | crosscutting modularity. </p> | 
|  |  | 
|  | <p> You can find the current binaries, source, documentation and | 
|  | an active user community for AspectJ at</p> | 
|  |  | 
|  | <blockquote> | 
|  | http://www.eclipse.org/aspectj | 
|  | </blockquote> | 
|  |  | 
|  | </div> | 
|  |  | 
|  | <img style="newpage" src="figures_classes.gif" height="900" alt="" /> | 
|  |  | 
|  | </body> </html> |