package lawOfDemeter; import java.util.*; import org.aspectj.lang.JoinPoint; /** * The Checker aspect is part of a Law of Demeter Checker - a set of * classes and aspects that verify a given program does not violate * the Law of Demeter. This aspect verifies that method calls do not * violate the Law of Demeter. * * @author David H. Lorenz * @author Modifications made by Paul Freeman */ public aspect Checker { /** * Prints a violation noitice using the thisJoinPoint argument. * Also provides a method that can be captured using the included pointcut * Checker.Violation(). * * @param thisJoinPoint */ pointcut Violation(JoinPoint tjp): execution(private void Checker.raiseViolation(JoinPoint)) && args(tjp); private void raiseViolation(JoinPoint thisJoinPoint){ System.out.println("!! LoD violation: "+thisJoinPoint+JPUtil.at(thisJoinPoint)); // used for debugging // printSuppliers(); } /** * Prints a success noitice using the thisJoinPoint argument. * Also provides a method that can be captured using the included pointcut * Checker.Success(). * * @param thisJoinPoint * @param binsIn */ pointcut Success(JoinPoint tjp, Vector binsIn): execution(private void Checker.raiseSuccess(JoinPoint, Vector)) && args(tjp, binsIn); private void raiseSuccess(JoinPoint thisJoinPoint, Vector binsIn){ // used for debugging // if(binsIn.size() > 1){ // System.out.println("Call OK ("+thisJoinPoint+")"+JPUtil.at(thisJoinPoint)+ // " target found in " + binsIn); // } // printSuppliers(binsIn); } /** * Advice that does the checking. */ before(): Any.ToCheck(){ Object thisObj = thisJoinPoint.getThis(); Object target = thisJoinPoint.getTarget(); Vector binsIn = new Vector(); // used for debugging // System.out.println("Checking--" + thisJoinPoint + JPUtil.at(thisJoinPoint)); // printSuppliers(); //check if target is in any of the available supplier bins Vector suppliers = Supplier.getSuppliers(); Iterator supIt = suppliers.iterator(); while(supIt.hasNext()){ Supplier thisBin = (Supplier)supIt.next(); if(thisBin.contains(target)){ binsIn.add(thisBin); } } if (binsIn.size() <= 0){ // if the target is not a preferred supplier -> Violation raiseViolation(thisJoinPoint); }else{ raiseSuccess(thisJoinPoint, binsIn); } } // used for debugging private void printSuppliers(){ Vector suppliers = Supplier.getSuppliers(); printSuppliers(suppliers); } // used for debugging private void printSuppliers(Vector suppliers){ Iterator supIt = suppliers.iterator(); while(supIt.hasNext()){ Supplier thisBin = (Supplier)supIt.next(); // used for debugging if(thisBin instanceof TargetBinStack){ ((TargetBinStack)thisBin).printAllTargets(); }else{ thisBin.printTargets(); } } } }