handout ClassForm checker


Subject: handout ClassForm checker
From: Karl Lieberherr (lieber@ccs.neu.edu)
Date: Fri Oct 11 2002 - 09:12:25 EDT


HW 4

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()
// <prefSuppliers> HashMap.

// aspect LoDPointCutsContext :
// Arguments | LocallyConstructed | ReturnValue common
// abstract pointcut positiveSituationsContext()
// <stackPrefSuppliers> 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<alloweds.length; i++) {
            if(targetType==alloweds[i])
               return;
          }
       }
       HashSet innermost = (HashSet) LoDPointCutsContext.stackPrefSuppliers.peek();

       if(innermost.contains(targetType))
             return;
             
       System.out.println("Violation Found at "+ thisJoinPoint.getSourceLocation().getFileName()+":"+thisJoinPoint.getSourceLocation().getLine()+":"+thisJoinPoint.getSourceLocation().getColumn() + " jp " + thisJoinPoint);
}
}

aspect DirectPart extends LoDPointCutsGlobal {
   public pointcut positiveSituationsGlobal():staticinitialization(*) && Any.scope();
   
   
   Class[] getAllowed (JoinPoint.StaticPart ejsp,JoinPoint.StaticPart jsp) {
         Class thisClass = jsp.getSignature().getDeclaringType();
         Field[] fields = thisClass.getDeclaredFields();
         Class[] v = new Class[fields.length];
         for(int i=0; i<fields.length; i++)
                    v[i]=fields[i].getType();
         return v;
    }
}

public aspect Arguments extends LoDPointCutsContext {

  pointcut positiveSituationsContext(): Any.Execution();

  Class[] getAllowed(JoinPoint.StaticPart ejsp,JoinPoint.StaticPart jsp) {
          return ((MethodSignature)jsp.getSignature()).getParameterTypes();
  }
}

public aspect LocallyConstructed extends LoDPointCutsContext {

  pointcut positiveSituationsContext():Any.ConstructorCall();
  
  Class[] getAllowed(JoinPoint.StaticPart ejsp,JoinPoint.StaticPart jsp) {
          Class[] v = new Class[1];
          v[0]= jsp.getSignature().getDeclaringType();
          return v;
  }

}

public aspect ReturnValue extends LoDPointCutsContext {

  pointcut positiveSituationsContext(): Any.Call();
  
  Class[] getAllowed (JoinPoint.StaticPart ejsp,JoinPoint.StaticPart jsp) {
         if(ejsp.getSignature().getDeclaringType() != jsp.getSignature().getDeclaringType())
                return null;

              Class[] v = new Class[1];
              v[0]= ((MethodSignature)jsp.getSignature()).getReturnType();
              return v;
  }
}



This archive was generated by hypermail 2b28 : Fri Oct 11 2002 - 09:12:27 EDT