-------------------------------------------------------------------------- Software Engineering Fall 2002 COM 3205 --------------------------------------------------------------------------- Assignment 4 Due date: Oct. 24, 2002 -------------------------------------------------------------------------- This assignment is stored in file $SE/hw/4 in file hw4-SE.txt -------------------------------------------------------------------------- Topics: Implementing a Crosscutting Style Rule Additional Reading: ====================================== Read section 20 of TPP. Is AspectJ an active code generator? To be discussed in class. PART 1: Below is the class form implementation per program execution in AspectJ. We discussed this design and implementation in class. The program is not perfect. It contains at least one bug that I put in. Read section 43 (Ruthless Testing) and 34 (Code That is Easy To Test) in TPP and discuss the testability of the program below. Improve its testability if needed and find out why the program is not perfect. Turn in a paragraph about the testability of the program and how you improved it and turn in your improved and corrected program. // Class Form of Law of Demeter // The structural aspect-oriented design: // class Any = // pointcut scope() // pointcut Call() // pointcut ConstructorCall() // pointcut Execution(). // class Allowed : LoDPointCutsGlobal | LoDPointCutsContext common // abstract method Class[] getAllowed(JoinPoint.StaticPart, JoinPoint.StaticPart). // // returns the preferred supplier classes. // // The first argument is the enclosing join point, // // the second argument the current join point. // aspect LoDPointCutsGlobal : DirectPart common // abstract pointcut positiveSituationsGlobal() // HashMap. // aspect LoDPointCutsContext : // Arguments | LocallyConstructed | ReturnValue common // abstract pointcut positiveSituationsContext() // Stack(HashSet) . // one aspect per LoD rule: clear separation of concerns // aspect DirectPart = // pointcut positiveSituationsGlobal(). // staticinitialization(*) // aspect Arguments = // pointcut positiveSituationsContext(). // Any.Execution() // aspect LocallyConstructed = // pointcut positiveSituationsContext(). // Any.ConstructorCall() // aspect ReturnValue = . // pointcut positiveSituationsContext(). // Any.Call(). // aspect Checker = // Relevant AspectJ knowledge: // staticinitialization(TypePattern) // Picks out a static initializer execution // join point of any of the types of the type pattern. package lawOfDemeter; /** * @author Pengcheng Wu */ import java.util.*; import org.aspectj.lang.reflect.*; import org.aspectj.lang.*; import java.lang.reflect.*; class Any { pointcut scope(): !within(lawOfDemeter..*); // not in this package pointcut Call(): scope() && call(* *(..)); // any call // including constructor calls? pointcut ConstructorCall(): scope() && call(*.new (..)); // any constructor pointcut Execution(): scope() && execution(* *(..)); // any execution }; public abstract class Allowed { abstract Class[] getAllowed (JoinPoint.StaticPart enclosingjsp, JoinPoint.StaticPart jsp); } public abstract aspect LoDPointCutsGlobal extends Allowed { abstract pointcut positiveSituationsGlobal(); public static HashMap prefSuppliers = new HashMap(); before(): positiveSituationsGlobal() { prefSuppliers.put(thisJoinPointStaticPart.getSignature().getDeclaringType(), getAllowed(thisEnclosingJoinPointStaticPart,thisJoinPointStaticPart)); } } public abstract aspect LoDPointCutsContext extends Allowed { abstract pointcut positiveSituationsContext(); public static Stack stackPrefSuppliers = new Stack(); before() : Any.Execution() { stackPrefSuppliers.push(new HashSet()); } before() : positiveSituationsContext() { HashSet aSet = (HashSet) stackPrefSuppliers.peek(); Class[] allowed=getAllowed(thisEnclosingJoinPointStaticPart, thisJoinPointStaticPart); if(allowed!=null && allowed.length!=0) aSet.addAll(Arrays.asList(allowed)); } after(): Any.Execution() { stackPrefSuppliers.pop(); } } aspect Checker { after(): Any.Call() { Class targetType = thisJoinPointStaticPart.getSignature().getDeclaringType(); Class thisType = thisEnclosingJoinPointStaticPart.getSignature().getDeclaringType(); if(LoDPointCutsGlobal.prefSuppliers.containsKey(thisType)) { Class[] alloweds = (Class[])LoDPointCutsGlobal.prefSuppliers.get(thisType); for(int i=0; i