CSC 123 AspectJ Assignment. Part A: The first part of the assignment is designed for you to become familiar with the basic mechanics of AspectJ. Consider the following class for rational numbers. It contains the basic operations for equality, addition, multiplication, and inversion. But there are several aspect of the program that can be improved. /////// class rational { public int n, d; //numerator and denominator public rational(int a, int b) {n=a; d=b;} // constructor public boolean equals(rational B) // compare B with this rational { return n*B.d == d*B.n; } public rational mult(rational B) // multiply B and this rational { return new rational(n*B.n, d*B.d); } // note non-destructive operation public rational add(rational B) // add B to this rational { int a = n*B.d + d*B.n; int b = d*B.d; return new rational(a,b); } public void invert() // invert the fraction destructively { int temp = n; n=d; d=temp; } public String toString() { return n+"/"+d; } // output } // class rational public class userationals { public static void main(String[] args) { rational A = new rational(1,2); rational B = new rational(2,3); System.out.println(A.mult(B)); System.out.println(A.equals(new rational(2,4))); rational C = new rational(1,0); } } /////// DO NOT CHANGE ANY CODE IN THE GIVEN JAVA PROGRAM ABOVE. ALL ASPECTS SHOULD BE IN SEPARATE FILES SO YOU CAN COMPILE ANY SUBSET. 1. Rationals are not in normal form, so write an aspect aspect normalization { ... that contains the gcd function. public static int rational.gcd(int a, int b) { if (a==0) return b; else return gcd(b%a,a); } Note that the function is a newly added member of the rational class. We've just dynamically altered both the interface and implementation of a class. Now write advice to reduce the rational after the constructor is called. Your first advice can be something like after(rational R): execution(rational.new(int,int)) && target(R) ... There's a sublety here you need to understand. Why is the pointcut "execution" instead of "call"? Because when the constructor is called, the "target" object has not yet been created! In addition to unreduced rationals, rationals such as -1/-2 should be normalized to 1/2, and 2/-3 should become -2/3 (move the sign to the numerator). To do this properly, you'll also need to write an advice for the invert function. 2. The denominator should never be zero, so write an aspect aspect errorprevention { ... The denominator can be set to zero by the constructor, or by the invert function. Whenever the contructor sets d to zero, print out a warning and set d to 1 instead. When the invert function tries to set d to zero, print out a warning and cancel the invert operation. Errors can also occur if the B parameter to equals, mult and add is null. For add and mult, write a SINGLE around advice that crosscuts both cases, returing the "this" rational instead (that is, 1/2 + null = 1/2). For the equals method, write an advice that returns false after printing out a warning. 3. (OPTIONAL) The output toString function is too simple. 0/2 should just be printed as 0, and 4/1 should be just be printed as 4. Write a aspect betteroutput { ... to make this correction. NOTE: you may have to explicitly call toString() for this aspect to take effect. You can change the sample code in main in order to illustrate your new aspect. By "change the sample code" I mean, of course, that you should do so via an advice. 4. Write an aspect profiling { ... that contains advice to count the number of times gcd is called by a program (ANY program, not just from your main). Exclude recursive calls from the count. Write an advice to report the count after the execution of main. -------------------- Part B. AT LEAST ONE OF THE FOLLOWING PROBLEMS SHOULD BE COMPLETED 1. On the web page there is a java version of "food visitors" program. Using aspectJ, add a new class of food such as "beverage" with a different attribute. Integrate it into your program as you did for the C# assignment but using aspectJ features. No part of the original java program can be touched, NOT EVEN MAIN! All changes must be done with aspects and advice. Write an adivce to test your new features after the execution of main. Be sure that the two visitor classes are "modified" to work with the new visitee class. 2. Do the problem described in the aopbank sample program. 3. Select two java programs you or others have written in the past, ones that used objects. It is theorized that approximately 85% of all variable access are reads, and only 15% are writes. We can count the number of times that an instance variable is "get" and "set" using advice and pointcuts. Tally the the number of reads and writes to all variables and report them. REMEBMER: don't change any original code. Do whatevery you need to do inside aspects, i.e, observe "separation of concern". 4. See aopasnb.txt for the "stick figures" program.