// The object that will store and convert the DJ // traversal object to the AspectJ aspect code. import edu.neu.ccs.demeter.dj.*; import edu.neu.ccs.demeter.aplib.EdgeI; import java.util.*; class AspectJTraversal { // the traversal graph that we have translated TraversalGraph traversalGraph; // the name of the traversal String traversalName; // the name of the aspect String aspectName; // the buffer containing the traversal code in aspectj StringBuffer aspectjTraversalCode; // the debug mode static boolean debug=false; static boolean addPrintingAdvice=false; AspectJTraversal(String tn, TraversalGraph tg) throws edu.neu.ccs.demeter.aplib.NoSuchClassGraphNodeException{ traversalGraph = tg; traversalName = tn; aspectjTraversalCode = traversal2AspectJ(tn, tg); } AspectJTraversal(ClassGraph cg, String tn, String st) throws edu.neu.ccs.demeter.aplib.NoSuchClassGraphNodeException{ TraversalGraph tg = new TraversalGraph(st, cg); traversalGraph = tg; traversalName = tn; aspectjTraversalCode = traversal2AspectJ(tn, tg); } // get the aspect name public String getAspectName() { return aspectName; } // get the name of the straversal public String getTraversalName() { return traversalName; } // get the traversal string public String toString() { return aspectjTraversalCode.toString(); } // Convert the traversal to AspectJ code protected StringBuffer traversal2AspectJ(String tn, TraversalGraph tg) throws edu.neu.ccs.demeter.aplib.NoSuchClassGraphNodeException{ // the sting buffers StringBuffer returnBuffer = new StringBuffer(); // intialize the traversal declaration String travString = tg.getStrategy().toString(); StringBuffer newStr = new StringBuffer(100); int lastNext = 0; for (int nextLine = travString.indexOf('\n'); nextLine > -1; nextLine = travString.indexOf('\n', nextLine+1)) { newStr.append(travString.substring(lastNext,nextLine).trim()); lastNext = nextLine +1; //System.out.println(newStr); } newStr.append(travString.substring(lastNext, travString.length()).trim()); //System.out.println("output: " + newStr); returnBuffer.append("// traversal " + tn + " : " + newStr + "\n"); returnBuffer.append("public aspect " + tn + "Traversal { \n"); aspectName = tn + "Traversal"; if (debug) System.out.println("Processing " + tn + ":" + newStr); // set up the node sets List nodeSets = tg.getNodeSets(); // loop through each node in the traversal graph for (Iterator iter = nodeSets.iterator(); iter.hasNext(); ) { Object node = iter.next(); String nodeName = getNodeName(node); if (debug) System.out.println("processing node: " + nodeName); StringBuffer travBodyStr = new StringBuffer(" public void " + nodeName + "." + tn + "(){\n"); StringBuffer travWrapperMethods = new StringBuffer(); List outgoingEdgeSets = getOutgoingEdges(node); List incomingEdgeSets = getIncomingEdges(node); // loop through each outgoing edge and process it for (Iterator iterEdge = outgoingEdgeSets.iterator(); iterEdge.hasNext(); ) { edu.neu.ccs.demeter.aplib.EdgeI currentEdge = (edu.neu.ccs.demeter.aplib.EdgeI) iterEdge.next(); if (currentEdge.isConstructionEdge()) { if (debug) System.out.println("Processing edge: -> " + nodeName + "," + currentEdge.getLabel() + "," + currentEdge.getTarget()); // add the actual traversal call, i.e. if (edgename!=null) trv_edgename(); travBodyStr.append(" if (" + currentEdge.getLabel() + " != null) " + tn +"_crossing_" + currentEdge.getLabel() + "();\n"); // add method for wrapper method call, i.e. class.trv_edgename() travWrapperMethods.append(" public void " + nodeName + "." + tn + "_crossing_" + currentEdge.getLabel() + "() { " + currentEdge.getLabel() + "." + tn + "();}\n"); } if (currentEdge.isInheritanceEdge()) { if (debug) System.out.println("Passing edge: :> " + nodeName + "," + currentEdge.getLabel() + "," + currentEdge.getTarget()); // add the actual traversal call, i.e. if (edgename!=null) trv_edgename(); } } // if this is a inherited class, i.e. target of a is-a // edge, then we should add traveral to the super class // i.e. super.trav(); //if (isInherited()) { //} // now add all the traversal code into the string buffer // that we're going to return travBodyStr.append(" }\n"); // if the wrapper methods is empty then there's no edges outgoing // from this node and make sure that there's no outgoing edges. if (outgoingEdgeSets.size() != 0 || incomingEdgeSets.size() != 0) { returnBuffer.append(travBodyStr); returnBuffer.append(travWrapperMethods); } else { if (debug) System.out.println("Skipping: " + travBodyStr); } } // add code for the point cut and advice that will print out // the traversal as it goes along // the form of the point cut and advice: // pointcut pointcut_tname () : call(public void tname*()); // before () : pointcut_tname () { // System.out.println(thisJoinPoint); // } if (addPrintingAdvice) { String pointcutname = "pointcut_" + tn; returnBuffer.append(" pointcut " + pointcutname + "() : call(public void " + tn + "*());\n"); returnBuffer.append(" before () : " + pointcutname + " () { \n"); returnBuffer.append(" System.out.println(thisJoinPoint);\n"); returnBuffer.append(" }\n"); } // add the final } for the aspect returnBuffer.append("}\n"); // end the traversal declaration //System.out.println(returnBuffer); return returnBuffer; } protected List getOutgoingEdges(Object node) { List edgeList = traversalGraph.getEdgeSets(); LinkedList newList = new LinkedList(); for (Iterator iter = edgeList.iterator(); iter.hasNext(); ){ EdgeI edge = ((TraversalGraph.EdgeSet)iter.next()).getEdge(); Object edgeNode = edge.getSource(); //System.out.println("compare = " + edgeNode + " == " + node); if (edgeNode.toString().compareTo(getNodeName(node))==0) { // System.out.println("add to list"); newList.add(edge); } } return newList; } protected List getIncomingEdges(Object node) { List edgeList = traversalGraph.getEdgeSets(); LinkedList newList = new LinkedList(); for (Iterator iter = edgeList.iterator(); iter.hasNext(); ){ EdgeI edge = ((TraversalGraph.EdgeSet)iter.next()).getEdge(); Object edgeNode = edge.getTarget(); //System.out.println("compare = " + edgeNode + " == " + node); if (edgeNode.toString().compareTo(getNodeName(node))==0) { //System.out.println("add to list"); newList.add(edge); } } return newList; } protected String getNodeName(Object node) { String nodeNameRaw = new String(node.toString()); String nodeName = nodeNameRaw.substring(0, nodeNameRaw.indexOf(':')); return nodeName; } }