package org.ntlab.deltaViewer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.ntlab.deltaExtractor.IAliasCollector; import org.ntlab.trace.FieldUpdate; import org.ntlab.trace.MethodExecution; import org.ntlab.trace.MethodInvocation; import org.ntlab.trace.Reference; import org.ntlab.trace.Statement; import com.mxgraph.model.mxICell; import com.mxgraph.util.mxPoint; public class DeltaLayout implements IObjectLayout { private mxPoint coordinatorPoint = new mxPoint(0, 100); @Override public void execute(DeltaGraphAdapter mxgraph, IObjectCallGraph objectCallGraph, IAliasCollector aliasCollector) { Set<mxICell> vertices = mxgraph.getCellToVertexMap().keySet(); Map<String, mxICell> idToVertexMap = new HashMap<>(); for (mxICell vertex: vertices) { idToVertexMap.put(vertex.getId(), vertex); } Statement relatedSt = objectCallGraph.getRelatedPoints().get(0).getStatement(); String srcObjId = null; String dstObjId = null; if (relatedSt instanceof FieldUpdate) { srcObjId = ((FieldUpdate) relatedSt).getContainerObjId(); dstObjId = ((FieldUpdate) relatedSt).getValueObjId(); } else if (relatedSt instanceof MethodInvocation) { MethodInvocation methodInvStatement = (MethodInvocation) relatedSt; MethodExecution calledMethodExec = methodInvStatement.getCalledMethodExecution(); String methodSignature = calledMethodExec.getSignature(); if (calledMethodExec.isCollectionType() && (methodSignature.contains("add(") || methodSignature.contains("set(") || methodSignature.contains("put(") || methodSignature.contains("push(") || methodSignature.contains("addElement("))) { srcObjId = calledMethodExec.getThisObjId(); dstObjId = calledMethodExec.getArguments().get(0).getId(); } else { return; } } else { return; } // reconstruct srcSide and dstSide List<Reference> srcSide = new ArrayList<>(); List<Reference> dstSide = new ArrayList<>(); List<Reference> references = new ArrayList<>(); references.addAll(objectCallGraph.getReferences()); while (references.size() > 0) { boolean found; do { found = false; for (Reference r: references) { if (r.getDstObjectId().equals(srcObjId)) { srcSide.add(r); references.remove(r); srcObjId = r.getSrcObjectId(); found = true; break; } } } while (found); do { found = false; for (Reference r: references) { if (r.getDstObjectId().equals(dstObjId)) { dstSide.add(r); references.remove(r); dstObjId = r.getSrcObjectId(); found = true; break; } } } while (found); } // layout double time = 150; double padding = 200; coordinatorPoint.setX(coordinatorPoint.getX() + (time * dstSide.size()) + padding); // ����(0, 0) double xCor = coordinatorPoint.getX(); double yCor = coordinatorPoint.getY(); //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. List<String> doneList = new ArrayList<>(); mxgraph.getModel().beginUpdate(); try { // Layout vertex object. // srcSide int srcSideSize = srcSide.size(); MethodExecution coordinator = objectCallGraph.getStartPoints().get(0); String coordinatorObjId = coordinator.getThisObjId(); String coordinatorClassName = coordinator.getThisClassName(); for (int i = srcSideSize - 1; i >= 0; i--) { Reference ref = srcSide.get(i); if (i == srcSideSize - 1 && !coordinatorObjId.equals(ref.getSrcObjectId()) && !coordinatorClassName.equals(ref.getSrcClassName())) { System.out.println("coordinator: " + coordinatorClassName + ", " + coordinatorObjId); coordinatorPoint.setX(coordinatorPoint.getX() + time * 2); xCor += time * 2; mxICell vertex = idToVertexMap.get(coordinatorObjId); setVertexCoordinate(mxgraph, vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))); doneList.add(coordinatorObjId); srcSideSize++; } System.out.println("srcSide: " + ref.getSrcClassName() + ", " + ref.isCreation() + ", " + ref.getSrcObjectId()); if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) { if (!doneList.contains(ref.getSrcObjectId())) { mxICell vertex = idToVertexMap.get(ref.getSrcObjectId()); setVertexCoordinate(mxgraph, vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))); doneList.add(ref.getSrcObjectId()); } if (!doneList.contains(ref.getDstObjectId())) { mxICell vertex = idToVertexMap.get(ref.getDstObjectId()); setVertexCoordinate(mxgraph, vertex, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i))); doneList.add(ref.getDstObjectId()); } } else { mxICell vertex = idToVertexMap.get(ref.getSrcObjectId()); setVertexCoordinate(mxgraph, vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))); doneList.add(ref.getSrcObjectId()); doneList.add(ref.getDstObjectId()); } } // dstSide int dstSideSize = dstSide.size(); int cnt = 0; for (int i = dstSideSize - 1; i >= 0; i--) { Reference ref = dstSide.get(i); if (i == dstSideSize - 1 && srcSideSize == 0 && !coordinatorObjId.equals(ref.getSrcObjectId()) && !coordinatorClassName.equals(ref.getSrcClassName())) { System.out.println("coordinator: " + coordinatorClassName + ", " + coordinatorObjId); coordinatorPoint.setX(coordinatorPoint.getX() + time * 2); xCor += time * 2; System.out.println(coordinatorPoint.getX() + ", " + xCor); mxICell vertex = idToVertexMap.get(coordinatorObjId); setVertexCoordinate(mxgraph, vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))); doneList.add(coordinatorObjId); dstSideSize++; } System.out.println("dstSide: " + ref.getSrcClassName() + ", " + ref.getDstClassName() + ", " + ref.isCreation()); if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) { if (!doneList.contains(ref.getSrcObjectId())) { mxICell vertex = idToVertexMap.get(ref.getSrcObjectId()); setVertexCoordinate(mxgraph, vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))); doneList.add(ref.getSrcObjectId()); cnt++; } if (!doneList.contains(ref.getDstObjectId())) { mxICell vertex = idToVertexMap.get(ref.getDstObjectId()); setVertexCoordinate(mxgraph, vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))); doneList.add(ref.getDstObjectId()); } } else { doneList.add(ref.getDstObjectId()); } } } finally { mxgraph.getModel().endUpdate(); } } private void setVertexCoordinate(DeltaGraphAdapter mxgraph, mxICell vertex, double x, double y) { mxgraph.getCellGeometry(vertex).setX(x); mxgraph.getCellGeometry(vertex).setY(y); } }