package lawOfDemeter.objectform; import java.util.*; import org.aspectj.lang.*; public abstract aspect LawofDemeter{ //interfaces public interface Checked{ } public interface MethodSupplier{ } public interface FieldSupplier{ } //abstract pointcuts public abstract pointcut Check(Object thiz, Checked target); public abstract pointcut ArgumentRule(); public abstract pointcut AssociatedRule(); public abstract pointcut Set(FieldSupplier target, Object value); //advice Object around(Object thiz, Checked target):Check(thiz, target){ //check the LOD if(!((MethodSupplier)thiz).contains(target) && !((FieldSupplier)thiz).containsSupplier(target)) System.out.println(" !! LoD Object Violation !! " + thisJoinPoint + " at " + thisJoinPoint.getSourceLocation()); return proceed(thiz, target); } Object around():AssociatedRule(){ Object r = proceed(); HashSet enclosingSet= (HashSet) MethodSupplier.st.peek(); enclosingSet.add(r); return r; } Object around():ArgumentRule(){ Vector v = new Vector(); Object[] args = thisJoinPoint.getArgs(); for(int i=0;i < args.length; i++) v.add(args[i]); HashSet newSet = new HashSet(); newSet.addAll(v); MethodSupplier.st.push(newSet); Object r = proceed(); MethodSupplier.st.pop(); return r; } Object around(FieldSupplier target, Object value): Set(target, value){ //context insensitive situation Object newObj = proceed(target, value); JoinPoint.StaticPart sp = thisJoinPointStaticPart; String fieldName = sp.getSignature(). getDeclaringType().getName() + ":" + sp.getSignature().getName(); if(target.fieldNames.containsKey(fieldName)) fieldName = (String) target.fieldNames.get(fieldName); else target.fieldNames.put(fieldName,fieldName); target.targets.put(fieldName, value); return newObj; } // MethodSupplier private static Stack MethodSupplier.st = new Stack(); private boolean MethodSupplier.contains(Object target){ if(this == target) return true; HashSet enclosingSet= (HashSet) st.peek(); return enclosingSet.contains(target); } //FieldSupplier private HashMap FieldSupplier.targets = new HashMap(); private HashMap FieldSupplier.fieldNames = new HashMap(); private boolean FieldSupplier.containsSupplier(Object supplier){ return targets.containsValue(supplier); } }