diff --git a/src/org/ntlab/deltaViewer/CollaborationViewer.java b/src/org/ntlab/deltaViewer/CollaborationViewer.java index 4cbfcc5..0fd1514 100644 --- a/src/org/ntlab/deltaViewer/CollaborationViewer.java +++ b/src/org/ntlab/deltaViewer/CollaborationViewer.java @@ -2,36 +2,30 @@ import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.geom.Path2D; +import java.awt.Point; import java.util.ArrayList; +import java.util.Collections; import java.util.List; -import java.util.Map; -import javax.swing.JPanel; - -import org.jgrapht.graph.DefaultEdge; -import org.jgrapht.graph.DirectedWeightedPseudograph; import org.ntlab.deltaExtractor.Alias; -import org.ntlab.deltaExtractor.ExtractedStructure; import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.deltaExtractor.Alias.AliasType; +import org.ntlab.deltaViewer.Edge.TypeName; +import org.ntlab.trace.ArrayAccess; +import org.ntlab.trace.FieldAccess; +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 org.ntlab.trace.TracePoint; -import com.mxgraph.canvas.mxGraphics2DCanvas; -import com.mxgraph.model.mxCell; -import com.mxgraph.shape.mxConnectorShape; -import com.mxgraph.shape.mxIShape; -import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.swing.view.mxInteractiveCanvas; -import com.mxgraph.util.mxConstants; +import com.mxgraph.model.mxICell; import com.mxgraph.util.mxPoint; -import com.mxgraph.util.mxUtils; -import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraphView; public class CollaborationViewer extends MagnetRONViewer { private IObjectCallGraph objectCallGraph; - private static Dimension VERTEX_OBJECT_SIZE = new Dimension(70, 70); - private static Dimension VERTEX_METHOD_EXECUTION_SIZE = new Dimension(55, 20); private double scale = 1; @@ -47,14 +41,13 @@ public void init(IObjectCallGraph objectCallGraph, IAliasCollector aliasCollector, IObjectLayout layout) { this.objectCallGraph = objectCallGraph; this.aliasCollector = aliasCollector; - // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. createObjectVertices(this.objectCallGraph); layout.execute(objectCallGraph, aliasCollector, objectToVertexMap); - createEdgeToObject(this.aliasCollector.getAliasList()); + createEdgeToObject(this.objectCallGraph, this.aliasCollector); } /** - * Initialize animation.�@�Đ��{�^���������Ƃ� + * Initialize animation.�@(�Đ��{�^���������Ƃ�) */ public void initAnimation() { // reflectCoordinates(mxgraph); // objectVertex��mxGraph�̍��W�𔽉f������(���[�U���w�肵�����W�ʒu�𔽉f) @@ -79,16 +72,6 @@ update(); } - private void createObjectVertices(IObjectCallGraph objectCallGraph) { - // TODO Auto-generated method stub - - } - - private void createEdgeToObject(List aliasList) { - // TODO Auto-generated method stub - - } - /** * Step to animation of specified alias. * @@ -108,6 +91,435 @@ * @param numFrame Current animation frame. */ public void stepToAnimation(int numFrame) { + // TODO Implement doLastAnimation to support plural Delta. + // TOD curFrame debug. + System.out.println("Frame: " + curFrame + "->" + numFrame); +// if (numFrame - curFrame == 1) { + List relatedPoints = objectCallGraph.getRelatedPoints(); + List aliasList = aliasCollector.getAliasList(); + Alias curFrameAlias = (0 < numFrame && numFrame <= aliasList.size()) ? aliasList.get(numFrame- 1) : null; + Alias numFrameAlias = (0 <= numFrame && numFrame < aliasList.size()) ? aliasList.get(numFrame) : null; + + if (numFrameAlias != null) { + if (curFrameAlias != null) { + for (TracePoint rp: relatedPoints) { + if (curFrameAlias.getTimeStamp() <= rp.getStatement().getTimeStamp() && rp.getStatement().getTimeStamp() <= numFrameAlias.getTimeStamp()) { + System.out.println("\r\nLast Animation."); + doLastAnimation(numFrame, rp); + return; + } + } + } + doAnimation(curFrame, numFrame); + } else if (curFrameAlias != null && numFrameAlias == null) { + System.out.println("\r\nLast Animation."); + doLastAnimation(numFrame, relatedPoints.get(relatedPoints.size() - 1)); + } else { + System.out.println("ERROR : Not exist alias."); + } +// } else { + // TODO Considering fast-forwarding animations. +// } + } + + private void doLastAnimation(int numFrame, TracePoint relatedPoint) { + // TODO Implement doLastAnimation to support plural Delta. + outputLog(); + curFrame = numFrame; + List aliasList = aliasCollector.getAliasList(); + Alias prevAlias = aliasList.get(numFrame - 1); + + // Make ObjectEdge and reset position of vertexObject, remove vertexMethodExecution. + Statement statement = relatedPoint.getStatement(); + MethodExecution prevMethodExec = prevAlias.getMethodExecution(); + if(statement instanceof FieldUpdate) { + // Format fieldName. + FieldUpdate fieldUpdateStatement = (FieldUpdate) statement; + String fieldNames[] = formatFieldName(fieldUpdateStatement.getFieldName()); + String fieldName = fieldNames[fieldNames.length-1]; + String sourceObjectId = fieldUpdateStatement.getContainerObjId(); + + createObjectRefrence(fieldUpdateStatement, fieldName); + + // Change! + String targetObjectId = fieldUpdateStatement.getValueObjId(); + ObjectVertex targetObjectVertex = objectToVertexMap.get(targetObjectId); + + if (methodExecToVertexMap.containsKey(prevMethodExec)) { + if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(targetObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getLocals().remove(targetObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + targetObjectVertex.getLabel()); + } else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(targetObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getArguments().remove(targetObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + targetObjectVertex.getLabel()); + } + } + + removeCalledMethodExecutionVertex(objectToVertexMap.get(sourceObjectId), prevMethodExec.getCallerMethodExecution(), prevMethodExec); + updateObjectVertices(); + } + + if(statement instanceof MethodInvocation) { + MethodInvocation methodInvStatement = (MethodInvocation) statement; + MethodExecution calledMethodExec = methodInvStatement.getCalledMethodExecution(); + String methodSignature = calledMethodExec.getSignature(); + String srcClassName = null; + String srcObjId = null; + String tgtObjId = null; + + //Array��List�̂Ƃ��������x����t����i�m���ɕ������Ă�����̂Ƃ�)getSignature->contains("List.get(") || "Map.get(") <�z���C�g���X�g> +// if (methodExec.getSignature().contains("List.add(") || +// methodExec.getSignature().contains("Map.put(")) { + if (calledMethodExec.isCollectionType() + && (methodSignature.contains("add(") + || methodSignature.contains("set(") + || methodSignature.contains("put(") + || methodSignature.contains("push(") + || methodSignature.contains("addElement("))) { + + srcClassName = calledMethodExec.getThisClassName(); + srcObjId = calledMethodExec.getThisObjId(); + tgtObjId = calledMethodExec.getArguments().get(0).getId(); + ObjectVertex tgtObjectVertex = objectToVertexMap.get(tgtObjId); + + createObjectRefrence(srcClassName, srcObjId, tgtObjId); + if (methodExecToVertexMap.containsKey(prevMethodExec)) { + if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(tgtObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getLocals().remove(tgtObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel()); + } else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(tgtObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getArguments().remove(tgtObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel()); + } + } + List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); + System.out.println(methodExecList.size()); + if (methodExecList.size() > 1) { + removeCalledMethodExecutionVertex(null, prevMethodExec.getCallerMethodExecution(), prevMethodExec); + } else { + removeCalledMethodExecutionVertex(null, null, prevMethodExec); + } + updateObjectVertices(); + } else { + // this to another + srcClassName = methodInvStatement.getThisClassName(); + srcObjId = methodInvStatement.getThisObjId(); + tgtObjId = calledMethodExec.getReturnValue().getId(); + ObjectVertex tgtObjectVertex = objectToVertexMap.get(tgtObjId); + + createObjectRefrence(srcClassName, srcObjId, tgtObjId); + if (methodExecToVertexMap.containsKey(prevMethodExec)) { + if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(tgtObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getLocals().remove(tgtObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel()); + } else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(tgtObjectVertex)) { + methodExecToVertexMap.get(prevMethodExec).getArguments().remove(tgtObjectVertex); + System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel()); + } + } + removeCalledMethodExecutionVertex(objectToVertexMap.get(srcObjId), prevMethodExec, calledMethodExec); + updateObjectVertices(); + } + + } + +// MethodExecution tempMethodExec = alias.getMethodExecution(); +// //Array��List�̂Ƃ��������x����t����i�m���ɕ������Ă�����̂Ƃ�)getSignature->contains("List.get(") || "Map.get(") <�z���C�g���X�g> +// if (tempMethodExec.getSignature().contains("List.add(") || +// tempMethodExec.getSignature().contains("Map.put(")) { +// String srcClassName = tempMethodExec.getThisClassName(); +// String fieldName = tempMethodExec.getArguments().get(0).getId(); +// System.out.println("rTHIS " + srcClassName + ", " + fieldName); +// } + +// Statement tempStatement = alias.getOccurrencePoint().getStatement(); -> MethodInvocation +// if(tempStatement instanceof FieldAccess) { +// FieldAccess fieldAccessStatement = (FieldAccess) tempStatement; +// String fieldNames[] = formatFieldName(fieldAccessStatement.getFieldName()); +// String srcClassName = fieldNames[0]; +// String fieldName = fieldNames[1]; +// String sourceObjectId = fieldAccessStatement.getContainerObjId(); +// System.out.println(fieldName); +// createObjectRefrence(fieldAccessStatement, fieldName); +// removeCalledMethodExecutionVertex(objectToVertexMap.get(sourceObjectId), alias.getMethodExecution().getCallerMethodExecution(), alias.getMethodExecution()); +// updateObjectVertices(); +// } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + Alias nextAlias = (numFrame < aliasList.size()) ? aliasList.get(numFrame) : null; + List meList = new ArrayList<>(methodExecToVertexMap.keySet()); + Collections.reverse(meList); + System.out.println(meList.size()); + for(int i = 0; i < meList.size(); i++) { + String objectId = meList.get(i).getThisObjId(); + ObjectVertex sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex + MethodExecution me = meList.get(i); + if (nextAlias != null && me.getSignature().equals(nextAlias.getMethodSignature())) break; + if (i != meList.size()-1) { + for(Statement st: me.getStatements()) { + if(st instanceof MethodInvocation) { + MethodExecution calledMethodExec = ((MethodInvocation) st).getCalledMethodExecution(); + String calledObjectId = calledMethodExec.getThisObjId(); + System.out.println(calledObjectId); + if(objectToVertexMap.containsKey(calledObjectId)) { + mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell(); + Point absolutePointCalledCell = getAbsolutePointforCell(calledCell); + System.out.println(objectId + ", " + me.getSignature()); +// objectToVertexMap.get(calledObjectId).resetCellPosition(); +// if (methodExecToVertexMap.get(methodExec).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExec).getLocals().contains(objectToVertexMap.get(calledObjectId))) { +// calledCell.getParent().remove(calledCell); +// calledCell.setParent(mxDefaultParent); +// calledCell.getGeometry().setX(absolutePointCalledCell.getX()); +// calledCell.getGeometry().setY(absolutePointCalledCell.getY()); +// deltaAnimation.setVertexAnimation(calledCell, new mxPoint(objectToVertexMap.get(calledObjectId).getInitialX(), objectToVertexMap.get(calledObjectId).getInitialY())); +// deltaAnimation.startVertexAnimation(); +// } + removeCalledMethodExecutionVertex(sourceVertexObject, me.getCallerMethodExecution(), me); + updateObjectVertices(); +// removeVertexMethodExecution(sourceVertexObject, methodExec); +// update(); + break; + } + } + } + } else { + outputLog(); + + // Change! + List arguments = new ArrayList<>(methodExecToVertexMap.get(me).getArguments()); + List locals = new ArrayList<>(methodExecToVertexMap.get(me).getLocals()); + if (arguments.size() != 0) { + for (ObjectVertex vo: arguments) { + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + methodExecToVertexMap.get(me).getArguments().remove(vo); + } + }else if (locals.size() != 0) { + for (ObjectVertex vo: locals) { + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + methodExecToVertexMap.get(me).getLocals().remove(vo); + } + } + updateObjectVertices(); + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + update(); + } + + /** + * Create vertices(mxGraph) and objectVertices in objectToVertexMap. Vertices(mxGraph) coordinate are appropriate. + * @param objectCallGraph + */ + private void createObjectVertices(IObjectCallGraph objectCallGraph) { + //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + // Create vertices(mxGraph) and objectVertices. + List refList = objectCallGraph.getReferences(); + int ocgSize = refList.size(); + double vertexObjWidth = VERTEX_OBJECT_SIZE.getWidth(); + double vertexObjHeight = VERTEX_OBJECT_SIZE.getHeight(); + + for (int i = 0; i < ocgSize; i++) { + Reference ref = refList.get(i); + if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) { + // srcSide + if (!objectToVertexMap.containsKey(ref.getSrcObjectId())) { + System.out.println("srcSide: " + ref.getSrcClassName() + ", " + ref.getSrcObjectId() + ": " + ref.isCreation()); + String srcClassName = ref.getSrcClassName(); + if (srcClassName.contains("[L")) { + srcClassName = formatArrayName(srcClassName); + } + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex. + objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0)); + } + // dstSide + if (!objectToVertexMap.containsKey(ref.getDstObjectId())) { + System.out.println("dstSide: " + ref.getDstClassName() + ", " + ref.getDstObjectId()); + String dstClassName = ref.getDstClassName(); + if (dstClassName.contains("[L")) { + dstClassName = formatArrayName(dstClassName); + } + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex. + objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, 0, 0)); + } + } else { + String srcClassName = ref.getSrcClassName(); + if (srcClassName.contains("[L")) { + srcClassName = formatArrayName(srcClassName); + } + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex. + objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0)); + objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), null, 0, 0)); + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Create MethodExecutionVertex. Be careful to refer objectCallGraph.getStartPoints() when curFrame is 0. + * + * @param alias + */ + @Override + public void createMethodExecutionVertex(Alias alias) { + String objId = alias.getObjectId(); + MethodExecution methodExec = alias.getMethodExecution(); + String methodExecSignature = methodExec.getSignature(); + + if (curFrame == 0) { + MethodExecution callerMethodExec = methodExec.getCallerMethodExecution(); + if (callerMethodExec != null && methodExecSignature != callerMethodExec.getSignature() && objectToVertexMap.containsKey(callerMethodExec.getThisObjId()) && objectCallGraph.getStartPoints().get(0) == callerMethodExec) { + createMethodExecutionVertex(callerMethodExec.getThisObjId(), callerMethodExec.getSignature(), callerMethodExec); + } + createMethodExecutionVertex(objId, methodExecSignature, methodExec); + } else if (alias.getObjectId().matches("0") && !methodExecToVertexMap.containsKey(methodExec)) { + createMethodExecutionVertex(objId, methodExecSignature, methodExec); + } + } + + /** + * + * @param ocg + * @param ac + */ + private void createEdgeToObject(IObjectCallGraph ocg, IAliasCollector ac) { + List relatedPoints = ocg.getRelatedPoints(); + int rpIndex = 0; // relatedPoints index + List aliasList = ac.getAliasList(); + + for (int i = 0; i < aliasList.size()-1; i++) { + Alias curAlias = aliasList.get(i); + Alias nextAlias = aliasList.get(i+1); + String curAliasObjId = curAlias.getObjectId(); // srcObjId + String nextAliasObjId = nextAlias.getObjectId(); // dstObjId + String srcClassName = null; + String fieldName = null; + + // Search for objectReference srcClassName, fieldName between curAlias and nexAlias. + if (curAlias.getAliasType() == AliasType.THIS) { + if (nextAlias.getAliasType() == AliasType.RETURN_VALUE) { + MethodExecution nextMethodExec = nextAlias.getMethodExecution(); + //Array��List�̂Ƃ��������x����t����i�m���ɕ������Ă�����̂Ƃ�)getSignature->contains("List.get(") || "Map.get(") <�z���C�g���X�g> + if (nextMethodExec.getSignature().contains("List.get(") || + nextMethodExec.getSignature().contains("Map.get(")) { + srcClassName = nextMethodExec.getThisClassName(); + fieldName = nextMethodExec.getArguments().get(0).getId(); + System.out.println("rTHIS " + srcClassName + ", " + nextMethodExec.getArguments().get(0).getId()); + } + } else { + Statement statement = nextAlias.getOccurrencePoint().getStatement(); + if(statement instanceof FieldAccess && curAliasObjId.equals(((FieldAccess)statement).getContainerObjId())) { + String fieldNames[] = formatFieldName(((FieldAccess)statement).getFieldName()); + srcClassName = fieldNames[0]; + fieldName = fieldNames[1]; + } + } + System.out.println("THIS " + srcClassName + "(" + curAliasObjId + ") -> " + "(" + nextAliasObjId + "), "+ fieldName); + } + + if(curAlias.getAliasType() == AliasType.ARRAY) { + Statement statement= nextAlias.getOccurrencePoint().getStatement(); + if(statement instanceof ArrayAccess) { + srcClassName = ((ArrayAccess)statement).getArrayClassName(); + int index = ((ArrayAccess)statement).getIndex(); + fieldName = formatArrayIndex(index); + System.out.println("ARRAY " + srcClassName + "(" + curAliasObjId + ") -> " + "(" + nextAliasObjId + "), " + fieldName); + } + } + + + if (srcClassName != null && fieldName != null && !edgeMap.containsKey(srcClassName + "." + fieldName)) { + // Judge AliasList contains relatedPoint. (If contains not to create edge.) + if (rpIndex < relatedPoints.size() - 1) { + TracePoint rp = relatedPoints.get(rpIndex); + Statement rpStatement = rp.getStatement(); + String rpSrcObjId = null; + String rpTgtObjId = null; + String rpSrcClassName = null; + String rpFieldName = null; + + // Search for relatedPoint objectReference srcClassName, fieldName. + if(rpStatement instanceof FieldUpdate) { + // Format fieldName. + FieldUpdate rpFieldUpdateStatement = (FieldUpdate) rpStatement; + rpSrcObjId = rpFieldUpdateStatement.getContainerObjId(); + rpTgtObjId = rpFieldUpdateStatement.getValueObjId(); + String rpFieldNames[] = formatFieldName(rpFieldUpdateStatement.getFieldName()); + rpSrcClassName = rpFieldNames[0]; + rpFieldName = rpFieldNames[rpFieldNames.length-1]; + } + + if(rpStatement instanceof MethodInvocation) { + MethodInvocation rpMethodInvStatement = (MethodInvocation) rpStatement; + MethodExecution rpCalledMethodExec = rpMethodInvStatement.getCalledMethodExecution(); + String rpMethodSig = rpCalledMethodExec.getSignature(); + + //Array��List�̂Ƃ��������x����t����i�m���ɕ������Ă�����̂Ƃ�)getSignature->contains("List.get(") || "Map.get(") <�z���C�g���X�g> + // if (rpMethodExec.getSignature().contains("List.add(") || + // rpMethodExec.getSignature().contains("Map.put(")) { + if (rpCalledMethodExec.isCollectionType() + && (rpMethodSig.contains("add(") + || rpMethodSig.contains("set(") + || rpMethodSig.contains("put(") + || rpMethodSig.contains("push(") + || rpMethodSig.contains("addElement("))) { + + rpSrcClassName = rpCalledMethodExec.getThisClassName(); + rpSrcObjId = rpCalledMethodExec.getThisObjId(); + rpTgtObjId = rpCalledMethodExec.getArguments().get(0).getId(); + } else { + // this to another + rpSrcClassName = rpMethodInvStatement.getThisClassName(); + rpSrcObjId = rpMethodInvStatement.getThisObjId(); + rpTgtObjId = rpCalledMethodExec.getReturnValue().getId(); + } + } + if (srcClassName.equals(rpSrcClassName) && fieldName.equals(rpFieldName) && curAliasObjId.equals(rpSrcObjId) && nextAliasObjId.equals(rpTgtObjId)) { + rpIndex++; + continue; + } + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + Object srcCell = objectToVertexMap.get(curAliasObjId).getCell(); + Object dstCell = objectToVertexMap.get(nextAliasObjId).getCell(); + if (srcCell != null && dstCell != null) { // isCreation() + System.out.println("makeEdgeObject: " + fieldName + ", " + srcClassName + " (" + srcCell.hashCode() + "), " + " (" + dstCell.hashCode() + ")"/* + ", " + dstClassName*/); + // BUG:NullPointerException + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, fieldName, srcCell, dstCell); + Point absPtSrcCell = getAbsolutePointforCell((mxICell)srcCell); + Point absPtDstCell = getAbsolutePointforCell((mxICell)dstCell); + setEdgePoint((mxICell)edge, absPtSrcCell, absPtDstCell); + edgeMap.put(srcClassName + "." + fieldName, new Edge(fieldName, TypeName.Reference, edge)); + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + } } } diff --git a/src/org/ntlab/deltaViewer/DeltaViewer.java b/src/org/ntlab/deltaViewer/DeltaViewer.java index c266200..9e218f1 100644 --- a/src/org/ntlab/deltaViewer/DeltaViewer.java +++ b/src/org/ntlab/deltaViewer/DeltaViewer.java @@ -2,24 +2,11 @@ import java.awt.BorderLayout; import java.awt.Dimension; -import java.awt.Graphics2D; import java.awt.Point; -import java.awt.geom.Path2D; -import java.awt.geom.Point2D; -import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import javax.swing.JFrame; -import javax.swing.JPanel; - -import org.jgrapht.graph.DefaultEdge; -import org.jgrapht.graph.DirectedWeightedPseudograph; import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.Delta; import org.ntlab.deltaExtractor.ExtractedStructure; @@ -27,7 +14,6 @@ import org.ntlab.deltaViewer.Edge.TypeName; import org.ntlab.deltaExtractor.Alias.AliasType; import org.ntlab.trace.ArrayAccess; -import org.ntlab.trace.ArrayUpdate; import org.ntlab.trace.FieldAccess; import org.ntlab.trace.FieldUpdate; import org.ntlab.trace.MethodExecution; @@ -35,17 +21,8 @@ import org.ntlab.trace.Reference; import org.ntlab.trace.Statement; -import com.mxgraph.canvas.mxGraphics2DCanvas; -import com.mxgraph.model.mxCell; import com.mxgraph.model.mxICell; -import com.mxgraph.shape.mxConnectorShape; -import com.mxgraph.shape.mxIShape; -import com.mxgraph.swing.mxGraphComponent; -import com.mxgraph.swing.view.mxInteractiveCanvas; -import com.mxgraph.util.mxConstants; import com.mxgraph.util.mxPoint; -import com.mxgraph.util.mxUtils; -import com.mxgraph.view.mxCellState; import com.mxgraph.view.mxGraphView; /** @@ -53,19 +30,11 @@ * * @author Nitta Lab. */ -//TASK: bArray O //Careful: Parent -//BUG: methodExecution Id. O -//BUG: Move ObjectVertex position sometimes. O -//BUG: Resize ObjectVertex sometimes. O -//BUG: finally field reference. O -//BUG: edge drawing order. -> parent -//BUG: methodExecution drawing order. -> parent -//BUG: ObjectVertex position when Resize ObjectVertex. O +//TODO BUG: edge drawing order. -> parent +//TODO BUG: methodExecution drawing order. -> parent public class DeltaViewer extends MagnetRONViewer { private ExtractedStructure eStructure; - private static Dimension VERTEX_OBJECT_SIZE = new Dimension(70, 70); - private static Dimension VERTEX_METHOD_EXECUTION_SIZE = new Dimension(55, 20); private mxPoint coordinatorPoint = new mxPoint(0, 100); private double scale = 1; @@ -73,16 +42,22 @@ public DeltaViewer() { super(); } - + + /** + * Set extractedStructure and aliasCollector, create vertex object and edge object. + * @param extractedStructure + * @param aliasCollector + */ public void init(ExtractedStructure extractedStructure, IAliasCollector aliasCollector) { this.eStructure = extractedStructure; this.aliasCollector = aliasCollector; - // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. createObjectVertices(eStructure); createEdgeToObject(this.aliasCollector.getAliasList()); } - /** Initialize JFrame, make vertex object and edge object. */ + /** + * Initialize animation.�@(�Đ��{�^���������Ƃ�) + */ public void initAnimation() { // Fit graph size in visible JFrame. mxGraphView view = mxgraphComponent.getGraph().getView(); @@ -108,46 +83,6 @@ update(); } - public void setExtractedStructure(ExtractedStructure extractedStructure) { - this.eStructure = extractedStructure; - } - - public void setDeltaAliasCollector(DeltaAliasTracker deltaAliasCollector) { - this.aliasCollector = deltaAliasCollector; - } - - public void setCoordinatorPoint(double x, double y) { - coordinatorPoint.setX(x); - coordinatorPoint.setY(y); - } - - -// private double getXForCell(String id) { -// double res = -1; -// if (objectToVertexMap.containsKey(id)) { -// Object cell = objectToVertexMap.get(id).getCell(); -// res = mxgraph.getCellGeometry(cell).getX(); -// } -// return res; -// } - -// private double getYForCell(String id) { -// double res = -1; -// if (objectToVertexMap.containsKey(id)) { -// Object cell = objectToVertexMap.get(id).getCell(); -// res = mxgraph.getCellGeometry(cell).getY(); -// } -// return res; -// } - -// private mxICell getRootParentCell(Object object) { -// mxICell cell = (mxICell) object; -// if(cell.getParent().getValue() == null) { -// return cell; -// } -// return getRootParentCell(cell.getParent()); -// } - /** * Step to animation of specified alias. * @@ -178,74 +113,9 @@ } /** - * Do animation from fromFrame to toFrame. - * - * @param fromFrame - * @param toFrame - */ - private void doAnimation(int fromFrame, int toFrame) { - for (int i = fromFrame; i <= toFrame; i++) { - List aliasList = new ArrayList<>(aliasCollector.getAliasList()); - Alias alias = aliasList.get(i); - System.out.println("\r\n" + i + ": " + alias.getAliasType().toString()); - System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo()); - switch(alias.getAliasType()) { - case RETURN_VALUE: - moveObjectVertex(alias); - update(); - break; - case METHOD_INVOCATION: - removeMethodExecutionVertex(alias); - moveObjectVertex(alias); - update(); - break; - case CONSTRACTOR_INVOCATION: - createObjectVertexOnConstractor(alias); - createMethodExecutionVertex(alias.getObjectId(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCallerSideMethodName(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution()); - update(); - removeMethodExecutionVertex(alias); - update(); - break; - case FORMAL_PARAMETER: - moveObjectVertex(alias); - update(); - break; - case ACTUAL_ARGUMENT: - moveObjectVertex(alias); - update(); - break; - case THIS: - if (curFrame == 0 || alias.getObjectId().matches("0")) { - createMethodExecutionVertex(alias); - update(); - } - break; - case RECEIVER: - // Make VertexMethodExecution of called method execution. - MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); - if (!methodExecToVertexMap.containsKey(calledMethodExec)) { - if (curFrame == 0) { - MethodExecution methodExec = alias.getMethodExecution(); - if (methodExec.getSignature() != calledMethodExec.getSignature() && objectToVertexMap.containsKey(methodExec.getThisObjId())) { - createMethodExecutionVertex(methodExec.getThisObjId(), methodExec.getSignature(), methodExec); - } - } - createMethodExecutionVertex(alias.getObjectId(), calledMethodExec.getSignature(), calledMethodExec); - update(); - } - break; - default: - break; - } - curFrame = i + 1; - outputLog(); - } - } - - /** * Make last animation of extracted delta. * - * @param numFrame AliasList size. + * @param numFrame Index of aliasList size. */ private void doLastAnimation(int numFrame) { outputLog(); @@ -448,7 +318,10 @@ update(); } - /** Create ObjectVertices. */ + /** + * Create vertices(mxGraph) and objectVertices in objectToVertexMap. + * @param eStructure + */ private void createObjectVertices(ExtractedStructure eStructure) { Delta delta = eStructure.getDelta(); double time = 150; @@ -550,454 +423,6 @@ } } - /** - * Create ObjectVertex when CONSTRACTOR_INVOCATION. - * @param alias - */ - private void createObjectVertexOnConstractor(Alias alias) { - ObjectVertex objectVertex = objectToVertexMap.get(alias.getObjectId()); - String sourceObjId = alias.getMethodExecution().getThisObjId(); - mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjId).getCell(); - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth * Math.sqrt(2) * 0.1; - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - MethodInvocation methodInvocation; - String fieldName = null; - if (!alias.getMethodExecution().isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { - methodInvocation = (MethodInvocation)alias.getOccurrencePoint().getStatement(); - fieldName = methodInvocation.getCallerSideMethodName(); - } - Point absPtSrcCell = getAbsolutePointforCell(sourceCell); - mxgraph.getModel().beginUpdate(); - try { - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. - objectVertex.setCell(vertex); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, sourceCell, vertex); - setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); - edgeMap.put(alias.getMethodExecution().getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); - setCellsStyle(); - deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); - deltaAnimation.startVertexAnimation(); - } finally { - mxgraph.getModel().endUpdate(); - } - } - - /** - * Create ObjectVertex when CONSTRACTOR_INVOCATION is preceded by FORMAL_PARAMETER. - * @param alias - */ - private void createObjectVertexOnConstractorByFormalParameter(Alias alias) { - ObjectVertex objectVertex = objectToVertexMap.get(alias.getObjectId()); // Create cell of this object vertex. - MethodExecution methodExec = alias.getMethodExecution(); - String srcObjId = methodExec.getArguments().get(0).getId(); - mxICell srcCell = (mxICell)objectToVertexMap.get(srcObjId).getCell(); - double srcWidth = srcCell.getGeometry().getWidth(); - double srcHeight = srcCell.getGeometry().getHeight(); - double overlapWidth = srcWidth * Math.sqrt(2) * 0.1; - double overlapHeight = srcHeight - (srcHeight * Math.sqrt(2) * 0.1); - Point absPtSrcCell = getAbsolutePointforCell(srcCell); - MethodInvocation methodInv; - String fieldName = null; - if (!methodExec.isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { - methodInv = (MethodInvocation)alias.getOccurrencePoint().getStatement(); - fieldName = methodInv.getCallerSideMethodName(); - } - mxgraph.getModel().beginUpdate(); - try { - Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. - objectVertex.setCell(vertex); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, srcCell, vertex); - setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); - edgeMap.put(methodExec.getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); - setCellsStyle(); - deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); - deltaAnimation.startVertexAnimation(); - } finally { - mxgraph.getModel().endUpdate(); - } - } - - private void createObjectRefrence(FieldUpdate fieldUpdateStatement, String fieldName) { - String sourceObjectId = fieldUpdateStatement.getContainerObjId(); - String targetObjectId = fieldUpdateStatement.getValueObjId(); - mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjectId).getCell(); - mxICell targetCell = (mxICell)objectToVertexMap.get(targetObjectId).getCell(); - Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); - - targetCell.getParent().remove(targetCell); - targetCell.setParent(mxDefaultParent); - targetCell.getGeometry().setX(absolutePointTargetCell.getX()); - targetCell.getGeometry().setY(absolutePointTargetCell.getY()); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldUpdateStatement.getFieldName(), fieldName, objectToVertexMap.get(sourceObjectId).getCell(), objectToVertexMap.get(targetObjectId).getCell()); - ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;"); - edgeMap.put(fieldUpdateStatement.getFieldName(), new Edge(fieldName, TypeName.Reference, edge)); - // System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); - deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(targetObjectId).getInitialX(), objectToVertexMap.get(targetObjectId).getInitialY())); - deltaAnimation.startVertexAnimation(); - targetCell.getGeometry().setX(objectToVertexMap.get(targetObjectId).getInitialX()); - targetCell.getGeometry().setY(objectToVertexMap.get(targetObjectId).getInitialY()); - } - - private void createObjectRefrence(String srcClassName, String srcObjId, String tgtObjId) { - mxICell targetCell; -// if (objectToVertexMap.containsKey(targetObjId)) { - targetCell = (mxICell)objectToVertexMap.get(tgtObjId).getCell(); -// } else { -// targetObjId = methodExec.getCallerMethodExecution().getArguments().get(0).getId(); -// targetCell = (mxICell)objectToVertexMap.get(targetObjId).getCell(); -// } - Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); - - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - targetCell.getParent().remove(targetCell); - targetCell.setParent(mxDefaultParent); - targetCell.getGeometry().setX(absolutePointTargetCell.getX()); - targetCell.getGeometry().setY(absolutePointTargetCell.getY()); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, tgtObjId, null, objectToVertexMap.get(srcObjId).getCell(), objectToVertexMap.get(tgtObjId).getCell()); - ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;"); - edgeMap.put(tgtObjId, new Edge(null, TypeName.Reference, edge)); -// System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); - deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(tgtObjId).getInitialX(), objectToVertexMap.get(tgtObjId).getInitialY())); - deltaAnimation.startVertexAnimation(); - targetCell.getGeometry().setX(objectToVertexMap.get(tgtObjId).getInitialX()); - targetCell.getGeometry().setY(objectToVertexMap.get(tgtObjId).getInitialY()); - } finally { - mxgraph.getModel().endUpdate(); - } - - System.out.println("rTHIS " + srcClassName + ", " + tgtObjId); - } - - /** - * SourceVertex move targetVertex. - * - * @param alias - */ - private void moveObjectVertex(Alias alias) { - // sourceVertex - ObjectVertex sourceObjectVertex = objectToVertexMap.get(alias.getObjectId()); - if (alias.getMethodExecution().isStatic() && !methodExecToVertexMap.containsKey(alias.getMethodExecution())) { - createMethodExecutionVertex(alias.getObjectId(), alias.getMethodExecution().getSignature(), alias.getMethodExecution()); - } - // targetVertex - MethodExecutionVertex targetMethodExecVertex = methodExecToVertexMap.get(alias.getMethodExecution()); - System.out.println("moveObjectVertex: " + targetMethodExecVertex); - System.out.println("moveObjectVertex: " + alias.getMethodExecution().isStatic()); - moveObjectVertex(alias, sourceObjectVertex, targetMethodExecVertex); - updateObjectVertices(); - } - - /** - * Parent : Source VertexObject move target VertexMethodExecution. - * - * @param alias - * @param sourceVertexObject Source VertexObject. - * @param targetVertexMethodExec Target VertexMethodExecution. - */ - private void moveObjectVertex(Alias alias, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - MethodExecution methodExec = alias.getMethodExecution(); - if (alias.getAliasType().equals(AliasType.RETURN_VALUE) || alias.getAliasType().equals(AliasType.METHOD_INVOCATION)) { - if (sourceVertexObject.getCell() == null && methodExec.isCollectionType()) { - if (methodExec.getArguments().isEmpty()) { - createObjectVertexOnConstractor(alias); - } else { - createObjectVertexOnConstractorByFormalParameter(alias); - } - } - moveLocalObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); - } else if (alias.getAliasType().equals(AliasType.FORMAL_PARAMETER)) { - moveArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); - } else if (alias.getAliasType().equals(AliasType.ACTUAL_ARGUMENT)) { - moveActualArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); - } - } - - /** - * Source VertexObject move target VertexMethodExecution to Local position from caller MethodExecution. - * - * @param callerMethodExec Caller MethodExecution. - * @param sourceVertexObject - * @param targetVertexMethodExec - */ - private void moveLocalObjectVertex(MethodExecution callerMethodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); - - if (sourceCell == targetCell.getParent()) { - System.out.println("nothing."); - return; - } - - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExec).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); - } - - if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExec).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); - } - - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - int time = targetVertexMethodExec.getLocals().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); - - // System.out.println(time); - - if(sourceCell.getParent().getValue() != null) { - Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); - sourceCell.getParent().remove(sourceCell); - } - - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - System.out.println("moveLocalObjectVertex: " + sourceCell.getId() + " (" + sourceCell.hashCode() + ")" + ", " + sourceCell.getParent().getId() + " (" + sourceCell.getParent().hashCode() + ")"); - System.out.println(" " + targetCell.getId() + " (" + targetCell.hashCode() + ")" + ", " + targetCell.getParent().getId() + " (" + targetCell.getParent().hashCode() + ")"); - - Point absolutePointTargetCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointTargetCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointTargetCell.getY()); - - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double targetWidth = targetCell.getGeometry().getWidth(); - double targetHeight = targetCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + sourceHeight)); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); - deltaAnimation.startVertexAnimation(); - - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + sourceHeight); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); - targetVertexMethodExec.getLocals().add(sourceVertexObject); - System.out.println("moveLocalObjectVertex: " + targetVertexMethodExec.getLabel() + " :Local: " + sourceVertexObject.getLabel()); - } finally { - mxgraph.getModel().endUpdate(); - } - } - - /** - * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. - * - * @param methodExec MethodExecution. - * @param sourceVertexObject move - * @param targetVertexMethodExec - */ - private void moveArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); - // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); - - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); - if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); - } - - if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); - } - - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - int time = targetVertexMethodExec.getArguments().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); - - // System.out.println(time); - - if(sourceCell.getParent().getValue() != null) { - Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); - sourceCell.getParent().remove(sourceCell); - } - - if (!isParent(targetCell, sourceCell)) { - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); - - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.startVertexAnimation(); - - // sourceCell.setParent(targetCell.getParent()); - // targetCell.getParent().insert(sourceCell); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); - targetVertexMethodExec.getArguments().add(sourceVertexObject); - System.out.println("moveArgumentObejctVertex" + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); - } else { // �d�l��̃o�O, ���[�v������ - outputLog(); -// try { - // ObjectVertex(sourceCell)�̃N���[������ -// mxICell cloneSourceCell = (mxICell) mxgraph.addCell(sourceCell.clone()); -// -// cloneSourceCell.setStyle("fillColor=#ffffff;opacity=50;shape=ellipse"); -// cloneSourceCell.setId("clone" + cloneSourceCell.getId()); -// cloneSourceCell.setValue(null); -// cloneSourceCell.setParent(sourceCell); -// sourceCell.insert(cloneSourceCell); -// cloneSourceCell.getGeometry().setX(0); -// cloneSourceCell.getGeometry().setX(0); -// cloneSourceCell.getGeometry().setY(0); - - // ����ObjectVertex - Point absPtSourceCell = getAbsolutePointforCell(sourceCell); - Point absPtTargetParentCell = getAbsolutePointforCell(targetCell.getParent()); - - sourceCell.remove(targetCell.getParent()); - targetCell.getParent().setParent(mxDefaultParent); - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - - targetCell.getParent().getGeometry().setX(absPtTargetParentCell.getX()); - targetCell.getParent().getGeometry().setY(absPtTargetParentCell.getY()); - sourceCell.getGeometry().setX(absPtSourceCell.getX() - absPtTargetParentCell.getX()); - sourceCell.getGeometry().setY(absPtSourceCell.getY() - absPtTargetParentCell.getY()); - sourceCell.setStyle("opacity=50;shape=ellipse"); - - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); -// double overlapWidth = targetCell.getGeometry().getWidth() / 2; - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() + overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.startVertexAnimation(); - outputLog(); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() + overlapWidth); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); - - targetVertexMethodExec.getArguments().add(sourceVertexObject); - -// } catch (CloneNotSupportedException e) { -// e.printStackTrace(); -// } - } - } finally { - mxgraph.getModel().endUpdate(); - } - } - - /** - * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. - * - * @param methodExec MethodExecution. - * @param sourceVertexObject - * @param targetVertexMethodExec - */ - private void moveActualArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { - mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); - mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); - // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); - - if (sourceCell == targetCell.getParent()) { - System.out.println("nothing."); - return; - } - - // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. - // MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); - System.out.println(methodExec.getSignature()); - System.out.println(sourceVertexObject.getLabel()); - // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { - // methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); - // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); - // } - // - // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { - // methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); - // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); - // } - if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getLocals().contains(sourceVertexObject)) { - methodExecToVertexMap.get(methodExec).getLocals().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); - } - - if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getArguments().contains(sourceVertexObject)) { - methodExecToVertexMap.get(methodExec).getArguments().remove(sourceVertexObject); - System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); - } - - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { -// int time = targetVertexMethodExec.getArguments().size(); -// int time = targetVertexMethodExec.getLocals().size() + 1; - int time = targetVertexMethodExec.getLocals().size(); - double sourceX = sourceCell.getGeometry().getX(); - double sourceY = sourceCell.getGeometry().getY(); - - System.out.println(time + ", " + targetVertexMethodExec.getLocals().size()); - // if (time == 0) time = 1; - - if(sourceCell.getParent().getValue() != null) { - Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); - sourceX = absolutePointSourceCell.getX(); - sourceY = absolutePointSourceCell.getY(); - sourceCell.getParent().remove(sourceCell); - } - - sourceCell.setParent(targetCell.getParent()); - targetCell.getParent().insert(sourceCell); - Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); - sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); - sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); - - double sourceWidth = sourceCell.getGeometry().getWidth(); - double sourceHeight = sourceCell.getGeometry().getHeight(); - double targetWidth = targetCell.getGeometry().getWidth(); - double targetHeight = targetCell.getGeometry().getHeight(); - double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); - double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); - -// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); - deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); - deltaAnimation.startVertexAnimation(); -// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); -// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); - sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time)); - sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); - - targetVertexMethodExec.getArguments().add(sourceVertexObject); - System.out.println("moveActualArgumentObjectVertex: " + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); - } finally { - mxgraph.getModel().endUpdate(); - } - } - // private void moveInitialObjectVertex(MethodExecution methodExecution) { // for(Statement statement: methodExecution.getStatements()) { // if(statement instanceof MethodInvocation) { @@ -1021,51 +446,30 @@ // } // } - /** Update ObjectVertices size and position. */ - private void updateObjectVertices() { - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology - mxgraph.getModel().beginUpdate(); - try { - for (ObjectVertex objectVertex: objectToVertexMap.values()) { - mxCell objectVertexCell = ((mxCell) objectVertex.getCell()); - if (objectVertexCell != null) { - int time = 0; - for (int i = 0; i < objectVertexCell.getChildCount(); i++) { - if (!(objectVertexCell.getChildAt(i).getId()).contains("clone")) { - time++; - } - } - if (time == 0) { - time = 1; - } - if(objectVertexCell.getGeometry().getWidth() != VERTEX_OBJECT_SIZE.getWidth() * time) { - System.out.println("updateVertexObjectSize: " + objectVertexCell.getGeometry().getWidth() + "->" + VERTEX_OBJECT_SIZE.getWidth() * time+ ", " + objectVertexCell.getId()); - Dimension targetDimension = new Dimension(); - targetDimension.setSize(VERTEX_OBJECT_SIZE.getWidth() * time, VERTEX_OBJECT_SIZE.getHeight() * time); - if (objectVertexCell.getParent() != mxDefaultParent && (objectVertexCell.getChildCount() != 0 || objectVertexCell.getGeometry().getWidth() > VERTEX_OBJECT_SIZE.getWidth() * time)) { - double overlapX = (targetDimension.getWidth() - objectVertexCell.getGeometry().getWidth()) / 2 / Math.sqrt(2); - double overlapY = (targetDimension.getHeight() - objectVertexCell.getGeometry().getHeight()) / 2 / Math.sqrt(2); - System.out.println("updateVertexObjectPosition: " + objectVertexCell.getGeometry().getX() + " - " + overlapX); - mxPoint targetPoint = new mxPoint(objectVertexCell.getGeometry().getX() - overlapX, objectVertexCell.getGeometry().getY() + overlapY); - for (MethodExecutionVertex methodExecVertex: methodExecToVertexMap.values()) { - List arguments = methodExecVertex.getArguments(); - if (arguments != null && arguments.contains(objectVertex)) { - targetPoint.setY(objectVertexCell.getGeometry().getY() - overlapY); - break; - } - } - deltaAnimation.setVertexAnimation(objectVertexCell, targetPoint); - deltaAnimation.startVertexAnimation(); - } - deltaAnimation.setResizeVertexAnimation(objectVertexCell, targetDimension); - deltaAnimation.startResizeVertexAnimation(); - } - } - } - } finally { - mxgraph.getModel().endUpdate(); - } - } + /** + * Update VertexObject of targetMethodExecCell size have sourceObjectCell. + * + * @param sourceObjectCell + * @param targetMethodExecCell + */ + // private void updateVertexObjectSize(mxICell sourceObjectCell, mxICell targetMethodExecCell) { + // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + // + // //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + // mxgraph.getModel().beginUpdate(); + // try { + // double preX = parentTargetMethodExecCell.getGeometry().getX(); + // double preY = parentTargetMethodExecCell.getGeometry().getY(); + // double preCenterX = parentTargetMethodExecCell.getGeometry().getCenterX(); + // double preCenterY = parentTargetMethodExecCell.getGeometry().getCenterY(); + // parentTargetMethodExecCell.getGeometry().setWidth(parentTargetMethodExecCell.getGeometry().getWidth() * 1.8); + // parentTargetMethodExecCell.getGeometry().setHeight(parentTargetMethodExecCell.getGeometry().getHeight() * 1.8); + // parentTargetMethodExecCell.getGeometry().setX(preX - (parentTargetMethodExecCell.getGeometry().getCenterX() - preCenterX)); + // parentTargetMethodExecCell.getGeometry().setY(preY - (parentTargetMethodExecCell.getGeometry().getCenterY() - preCenterY)); + // } finally { + // mxgraph.getModel().endUpdate(); + // } + // } /** * Update VertexObject of targetMethodExecCell size have sourceObjectCell. @@ -1093,11 +497,12 @@ // } /** - * Create MethodExecutionVertex. + * Create MethodExecutionVertex. Be careful to refer eStructure#getCoordinator() when curFrame is 0. * * @param alias */ - private void createMethodExecutionVertex(Alias alias) { + @Override + public void createMethodExecutionVertex(Alias alias) { String objId = alias.getObjectId(); MethodExecution methodExec = alias.getMethodExecution(); String methodExecSignature = methodExec.getSignature(); @@ -1113,301 +518,6 @@ } } - /** - * Parent : Create MethodExecutionVertex. - * - * @param objId - * @param methodSignature Called or this MethodSignature. - * @param methodExec Called or this MethodExecution. - */ - private void createMethodExecutionVertex(String objId, String methodSignature, MethodExecution methodExec) { - - if (methodSignature.matches(".+\\(.*\\)")) { - System.out.println(methodSignature); - methodSignature = formatMethodSignature(methodSignature, methodExec.getThisClassName()); - } - - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - if (methodExec.isStatic() && !objId.equals("0")) { - objId = methodExec.getCallerMethodExecution().getThisObjId(); - } - - Object object = objectToVertexMap.get(objId).getCell(); - -// if (object != null) { - double xCor = VERTEX_OBJECT_SIZE.getWidth() * 0.1; - double yCor = VERTEX_OBJECT_SIZE.getHeight() * 0.5; - double standardX = xCor; - double standardY = 0; - int time = objectToVertexMap.get(objId).getVertexMethodExecutions().size(); - System.out.println(time); - if (time >= 1) { - mxICell standardCell = (mxICell) objectToVertexMap.get(objId).getVertexMethodExecutions().get(0).getCell(); - standardX = standardCell.getGeometry().getX(); - standardY = standardCell.getGeometry().getY(); - time-=1; - } - - Object vertex = mxgraph.insertDeltaVertex(object, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. - System.out.println("makeVertexMethodExecution: " + ((mxICell)vertex).getId() + " in " + objId + " (" + standardX + ", " + yCor * (time + 1) + standardY + ")"); - - MethodExecutionVertex vertexMethodExecution = new MethodExecutionVertex(methodSignature, vertex, standardX , yCor * (time + 1) + standardY, VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); - // Object vertex = mxgraph.insertVertex(object, methodSignature, methodSignature, 0, 0, 0, 0, "fillColor=white", true); //creates a white vertex. - // Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. - // VertexMethodExecution vertexMethodExecution = new VertexMethodExecution(methodSignature, vertex, getXForCell(objectId) + (xCor * (time + 1)), getYForCell(objectId) + (yCor * (time + 1)), VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); - methodExecToVertexMap.put(methodExec, vertexMethodExecution); - if(methodExecToVertexMap.size() > 1) { - ((mxICell)vertex).setVisible(false); - createEdgeToMethodExecution(); - } - objectToVertexMap.get(objId).addMethodExecution(vertexMethodExecution); -// } - } finally { - mxgraph.getModel().endUpdate(); - } - setCellsStyle(); - } - - /** - * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. - * - * @param alias - */ - private void removeMethodExecutionVertex(Alias alias) { - // sourceVertex - ObjectVertex sourceVertexObject = objectToVertexMap.get(alias.getObjectId()); - MethodExecution methodExec = alias.getMethodExecution(); - - if(alias.getAliasType().equals(AliasType.METHOD_INVOCATION) || alias.getAliasType().equals(AliasType.CONSTRACTOR_INVOCATION)) { - MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - List arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); - List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); - if (arguments.size() != 0) { - for (ObjectVertex vo: arguments) { - if (vo != sourceVertexObject) { - System.out.println("argumentRemove"); - mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); - cell.getParent().remove(cell); - cell.setParent(mxDefaultParent); - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); - deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); - deltaAnimation.startVertexAnimation(); - methodExecToVertexMap.get(calledMethodExec).getArguments().remove(vo); - } - } - } - if (locals.size() != 0) { - for (ObjectVertex vo: locals) { - if (vo != sourceVertexObject) { - System.out.println("localRemove"); - mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); - cell.getParent().remove(cell); - cell.setParent(mxDefaultParent); - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); - deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); - deltaAnimation.startVertexAnimation(); - methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); - } - } - } - } finally { - mxgraph.getModel().endUpdate(); - } - - - removeCalledMethodExecutionVertex(sourceVertexObject, methodExec, calledMethodExec); - } else { - removeMethodExecutionVertex(sourceVertexObject, methodExec); - } - } - - /** - * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. - * - * @param sourceVertexObject - * @param methodExec - */ - private void removeMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec) { - // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(methodExec)) { - mxCell targetVertexCell = (mxCell)methodExecToVertexMap.get(methodExec).getCell(); - targetVertexCell.getParent().remove(targetVertexCell); - targetVertexCell.setParent(mxDefaultParent); - mxgraph.removeCells(new Object[] {targetVertexCell}); - objectToVertexMap.get(methodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(methodExec)); - methodExecToVertexMap.remove(methodExec); - edgeMap.remove(methodExec.getSignature()); - updateObjectVertices(); - } - } - - /** - * Remove CalledVertexMethodExecution on AliasType is MethodInvocation of alias. - * - * @param sourceVertexObject - * @param methodExec - * @param calledMethodExec - */ - private void removeCalledMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec, MethodExecution calledMethodExec) { - outputLog(); - - // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. - if (methodExecToVertexMap.containsKey(calledMethodExec)) { - mxICell sourceVertexCell = null; - mxCell targetVertexCell = null; - - if (methodExec != null) { - sourceVertexCell = (mxICell)methodExecToVertexMap.get(methodExec).getCell(); - targetVertexCell = (mxCell)methodExecToVertexMap.get(calledMethodExec).getCell(); - } -// if(!calledMethodExec.isStatic()) { - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - mxgraph.getModel().beginUpdate(); - try { - // Dangerous - List arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); - List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); - if (arguments.size() != 0) { - for (ObjectVertex vo: arguments) { - if (vo != sourceVertexObject) { - mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); - System.out.println(cell); - System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); - System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); - System.out.println(absolutePointCell); - if (cell.getParent() != mxDefaultParent) { - cell.getParent().remove(cell); - cell.setParent(mxDefaultParent); - } - if (!absolutePointCell.equals(vo.getInitialPoint())) { - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); - deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); - deltaAnimation.startVertexAnimation(); - } - methodExecToVertexMap.get(calledMethodExec).getArguments().remove(vo); - } - } - } - if (locals.size() != 0) { - for (ObjectVertex vo: locals) { - if (vo != sourceVertexObject) { - mxICell cell = (mxICell)vo.getCell(); - Point absolutePointCell = getAbsolutePointforCell(cell); - System.out.println(cell); - System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); - System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); - System.out.println(absolutePointCell); - if (cell.getParent() != mxDefaultParent) { - cell.getParent().remove(cell); - cell.setParent(mxDefaultParent); - } - if (!absolutePointCell.equals(vo.getInitialPoint())) { - cell.getGeometry().setX(absolutePointCell.getX()); - cell.getGeometry().setY(absolutePointCell.getY()); - deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); - deltaAnimation.startVertexAnimation(); - } - methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); - } - } - } - - if (sourceVertexCell == null || targetVertexCell == null) return; - - mxgraph.removeCells(mxgraph.getEdgesBetween(sourceVertexCell, targetVertexCell)); - try { - mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); - Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); - Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); - cloneTargetVertexCell.getGeometry().setX(absolutPointTargetVertexCell.getX()); - cloneTargetVertexCell.getGeometry().setY(absolutPointTargetVertexCell.getY()); - cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); - cloneTargetVertexCell.setValue(null); - Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); - ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); - deltaAnimation.setReductionEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointSourceVertexCell.getX(), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight())); - deltaAnimation.startReductionEdgeAnimation(); -// deltaAnimation.setReductionEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); -// deltaAnimation.startReductionEdgeAnimation(); - mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - } finally { - mxgraph.getModel().endUpdate(); - } - ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); - targetVertexCell.setParent(mxDefaultParent); - mxgraph.removeCells(new Object[] {targetVertexCell}); - if (!calledMethodExec.isStatic()) { - objectToVertexMap.get(calledMethodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); - } else { - objectToVertexMap.get(calledMethodExec.getCallerMethodExecution().getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); - } - methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); - methodExecToVertexMap.remove(calledMethodExec); - edgeMap.remove(methodExec.getSignature()); -// moveInitialVertexObject(methodExec); -// updateObjectVerticesSize(); -// } else { -// ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); -// targetVertexCell.setParent(mxDefaultParent); -// mxgraph.removeCells(new Object[] {targetVertexCell}); -// methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); -// methodExecToVertexMap.remove(calledMethodExec); -// } - } - outputLog(); - } - - - /** - * Update VertexObject of targetMethodExecCell size have sourceObjectCell. - * - * @param sourceObjectCell - * @param targetMethodExecCell - */ - // private void updateVertexObjectSize(mxICell sourceObjectCell, mxICell targetMethodExecCell) { - // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); - // - // //Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. - // mxgraph.getModel().beginUpdate(); - // try { - // double preX = parentTargetMethodExecCell.getGeometry().getX(); - // double preY = parentTargetMethodExecCell.getGeometry().getY(); - // double preCenterX = parentTargetMethodExecCell.getGeometry().getCenterX(); - // double preCenterY = parentTargetMethodExecCell.getGeometry().getCenterY(); - // parentTargetMethodExecCell.getGeometry().setWidth(parentTargetMethodExecCell.getGeometry().getWidth() * 1.8); - // parentTargetMethodExecCell.getGeometry().setHeight(parentTargetMethodExecCell.getGeometry().getHeight() * 1.8); - // parentTargetMethodExecCell.getGeometry().setX(preX - (parentTargetMethodExecCell.getGeometry().getCenterX() - preCenterX)); - // parentTargetMethodExecCell.getGeometry().setY(preY - (parentTargetMethodExecCell.getGeometry().getCenterY() - preCenterY)); - // } finally { - // mxgraph.getModel().endUpdate(); - // } - // } - - private void setEdgePoint(mxICell edge, Point absPtSrcCell, Point absPtTgtCell) { - if(absPtSrcCell.getX() < absPtTgtCell.getX()) { - // if(isSrcSideChanged) { - // �E�����獶��փG�b�W������ - edge.setStyle("exitX=1;exitY=1;exitPerimeter=1;entryX=0;entryY=0;entryPerimeter=1;"); - } else { - // ��������E��փG�b�W������ - edge.setStyle("exitX=0;exitY=1;exitPerimeter=1;entryX=1;entryY=0;entryPerimeter=1;"); - } - } - /** Make edge object in JGraphT and draw this in JGraphX. * * @param aliasList @@ -1470,164 +580,44 @@ } } - /** Make EdgeMethodExecution. */ - private void createEdgeToMethodExecution() { - List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); - - // BUG : Edge Orientation Reverse. - for (int i = 0; i < methodExecList.size() - 1; i++) { - MethodExecution sourceMethodExec = methodExecList.get(i); - MethodExecution targetMethodExec = methodExecList.get(i + 1); - String methodSignature = sourceMethodExec.getSignature(); - if (!edgeMap.containsKey(methodSignature)) { - mxICell sourceVertexCell = (mxICell)methodExecToVertexMap.get(sourceMethodExec).getCell(); - mxICell targetVertexCell = (mxICell)methodExecToVertexMap.get(targetMethodExec).getCell(); -// if (!targetMethodExec.isStatic()) { - Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); - Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); - // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology - mxgraph.getModel().beginUpdate(); - try { - try { - mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); - cloneTargetVertexCell.getGeometry().setX(absolutPointSourceVertexCell.getX()); - cloneTargetVertexCell.getGeometry().setY(absolutPointSourceVertexCell.getY() + targetVertexCell.getGeometry().getHeight()); - cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); - cloneTargetVertexCell.setValue(null); - cloneTargetVertexCell.setVisible(true); - Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); - ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); - deltaAnimation.setExpandEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointTargetVertexCell.getX(), absolutPointTargetVertexCell.getY())); - deltaAnimation.startExpandEdgeAnimation(); - targetVertexCell.setVisible(true); -// deltaAnimation.setExpandEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); -// deltaAnimation.startExpandEdgeAnimation(); - Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, methodSignature, null, sourceVertexCell, targetVertexCell); - ((mxCell)edge).getParent().remove(((mxCell)edge)); - ((mxCell)edge).setParent(mxDefaultParent); - mxgraph.orderCells(false, new Object[] {edge}); - ((mxCell)edge).setStyle("exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;"); - mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); - edgeMap.put(methodSignature, new Edge(methodSignature, TypeName.Call, edge)); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - } finally { - mxgraph.getModel().endUpdate(); - } -// } else { -// targetVertexCell.setVisible(true); -// } - - } - } + public void setExtractedStructure(ExtractedStructure extractedStructure) { + this.eStructure = extractedStructure; } - private int countChildVertex(ObjectVertex vertexObject) { - int time = vertexObject.getVertexMethodExecutions().size(); - if(time == 0) { - return 1; - } - for(MethodExecutionVertex vertexMethodExecution: vertexObject.getVertexMethodExecutions()) { - for(ObjectVertex vo: vertexMethodExecution.getLocals()) { - time += countChildVertex(vo); - } - for(ObjectVertex vo: vertexMethodExecution.getArguments()) { - return countChildVertex(vo); - } - } - System.out.println(vertexObject.getLabel() + ": " + time); - return time; + public void setDeltaAliasCollector(IAliasCollector aliasCollector) { + this.aliasCollector = aliasCollector; } - private String[] formatFieldName(String fieldName) { - String fieldNames[] = fieldName.split("\\."); - String names[] = new String[] {fieldNames[0], fieldNames[fieldNames.length - 1]}; - for(int i = 1; i < fieldNames.length - 1; i++) { - names[0] += "." + fieldNames[i]; - } - return names; + public void setCoordinatorPoint(double x, double y) { + coordinatorPoint.setX(x); + coordinatorPoint.setY(y); } - private String formatMethodSignature(String methodSignature, String thisClassName) { - // Step1 : split "(" - String[] methodSignatures = methodSignature.split("\\("); - methodSignature = methodSignatures[0]; - // Step2 : split " " - methodSignatures = methodSignature.split(" "); - String tmpMethodSignature = methodSignatures[methodSignatures.length-1]; - // Step2 : split "." - String[] thisClassNames = thisClassName.split("\\."); - methodSignatures = tmpMethodSignature.split("\\."); - StringBuffer sb = new StringBuffer(); - int i = methodSignatures.length - 2; - if (i >= 0 && !thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i])) { - if (thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i + 1])) i += 1; - sb.append(methodSignatures[i]); - if (methodSignatures.length - i > 1) sb.append("."); - } - for (i = i + 1; i < methodSignatures.length; i++) { - sb.append(methodSignatures[i]); - if (methodSignatures.length - i > 1) sb.append("."); - } - sb.append("()"); - - String newMethodSignature = sb.toString(); - if (!newMethodSignature.isEmpty()) { - return newMethodSignature; - } - return methodSignature; - } - private String formatArrayName(String srcClassName) { - // Step1 : remove "[L" - StringBuffer sb = new StringBuffer(); - sb.append(srcClassName.substring(2, srcClassName.length()-1)); - sb.append("[]"); - return sb.toString(); - } +// private double getXForCell(String id) { +// double res = -1; +// if (objectToVertexMap.containsKey(id)) { +// Object cell = objectToVertexMap.get(id).getCell(); +// res = mxgraph.getCellGeometry(cell).getX(); +// } +// return res; +// } - private String formatArrayIndex(int index) { - StringBuffer sb = new StringBuffer(); - sb.append("["); - sb.append(index); - sb.append("]"); - return sb.toString(); - } +// private double getYForCell(String id) { +// double res = -1; +// if (objectToVertexMap.containsKey(id)) { +// Object cell = objectToVertexMap.get(id).getCell(); +// res = mxgraph.getCellGeometry(cell).getY(); +// } +// return res; +// } - private void outputLog() { - for (Object object: mxgraph.getChildCells(mxDefaultParent)) { - System.out.println(object + " " + object.hashCode()); - for (int i = 0; i < ((mxICell)object).getChildCount(); i++) { - System.out.println(" " + ((mxICell)object).getChildAt(i) + " " + object.hashCode()); - } - } - System.out.println("\nObject"); - for (Entry e: objectToVertexMap.entrySet()) { - String objId = e.getKey(); - ObjectVertex vo = e.getValue(); - if (vo.getCell() != null) { - System.out.println(vo.getLabel() + " (" + objId + ")" + " " + vo.getCell().hashCode()); - } else { - System.out.println(vo.getLabel() + " (" + objId + ")"); - } - for (MethodExecutionVertex vme: vo.getVertexMethodExecutions()) { - System.out.println(" " + vme.getLabel()); - for (ObjectVertex vmevo: vme.getArguments()) { - System.out.println(" Argument: " + vmevo.getLabel()); - } - for (ObjectVertex vmevo: vme.getLocals()) { - System.out.println(" Local: " + vmevo.getLabel()); - } - } - } - System.out.println("\nEdge"); - for (Edge e: edgeMap.values()) { - System.out.println(e.getLabel() + "(" + ((mxICell)e.getCell()).getId() + ")"); - if (((mxICell)e.getCell()).getParent() != null) { - System.out.println(" " + ((mxICell)e.getCell()).getParent().getId()); - } - } - } - +// private mxICell getRootParentCell(Object object) { +// mxICell cell = (mxICell) object; +// if(cell.getParent().getValue() == null) { +// return cell; +// } +// return getRootParentCell(cell.getParent()); +// } + } diff --git a/src/org/ntlab/deltaViewer/DeltaViewerSample.java b/src/org/ntlab/deltaViewer/DeltaViewerSample.java index d505b5d..3c5d7ff 100644 --- a/src/org/ntlab/deltaViewer/DeltaViewerSample.java +++ b/src/org/ntlab/deltaViewer/DeltaViewerSample.java @@ -1,27 +1,5 @@ package org.ntlab.deltaViewer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; - -import org.ntlab.deltaExtractor.Alias; -import org.ntlab.deltaExtractor.DeltaExtractorJSON; -import org.ntlab.deltaExtractor.ExtractedStructure; -import org.ntlab.trace.FieldAccess; -import org.ntlab.trace.FieldUpdate; -import org.ntlab.trace.IStatementVisitor; -import org.ntlab.trace.MethodExecution; -import org.ntlab.trace.MethodInvocation; -import org.ntlab.trace.ObjectReference; -import org.ntlab.trace.Reference; -import org.ntlab.trace.Statement; -import org.ntlab.trace.ThreadInstance; -import org.ntlab.trace.Trace; -import org.ntlab.trace.TraceJSON; -import org.ntlab.trace.TracePoint; - /** * Delta viewer sample for MagnetRON. * @@ -29,6 +7,7 @@ */ public class DeltaViewerSample { public static void main(String[] args) { + // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. MagnetRONFrame frame = new MagnetRONFrame(); frame.setVisible(true); frame.startAnimation(); diff --git a/src/org/ntlab/deltaViewer/MagnetRONViewer.java b/src/org/ntlab/deltaViewer/MagnetRONViewer.java index e03978b..608a7ef 100644 --- a/src/org/ntlab/deltaViewer/MagnetRONViewer.java +++ b/src/org/ntlab/deltaViewer/MagnetRONViewer.java @@ -19,7 +19,11 @@ import org.jgrapht.graph.DirectedWeightedPseudograph; import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.deltaExtractor.Alias.AliasType; +import org.ntlab.deltaViewer.Edge.TypeName; +import org.ntlab.trace.FieldUpdate; import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.MethodInvocation; import com.mxgraph.canvas.mxGraphics2DCanvas; import com.mxgraph.model.mxCell; @@ -38,12 +42,16 @@ protected static Dimension DEFAULT_SIZE = new Dimension(1300, 700); protected static String WINDOW_TITLE = "Delta Viewer"; + protected static Dimension VERTEX_OBJECT_SIZE = new Dimension(70, 70); + protected static Dimension VERTEX_METHOD_EXECUTION_SIZE = new Dimension(55, 20); + protected IAliasCollector aliasCollector; protected Map objectToVertexMap = new HashMap<>(); protected Map methodExecToVertexMap = new LinkedHashMap<>(); protected Map edgeMap = new HashMap<>(); + protected DeltaGraphAdapter mxgraph; protected mxICell mxDefaultParent; protected mxGraphComponent mxgraphComponent; @@ -64,6 +72,906 @@ add(mxgraphComponent, BorderLayout.CENTER); } + abstract public void initAnimation(); + + /** + * Step to animation of specified alias. + * + * @param alias Alias type and occurrence point etc. + */ + abstract public void stepToAnimation(Alias alias); + + /** + * Parent : Step to animation of specified numFrame. + * + * @param numFrame Current animation frame. + */ + abstract public void stepToAnimation(int numFrame); + + /** + * Do animation from fromFrame to toFrame. + * + * @param fromFrame + * @param toFrame + */ + protected void doAnimation(int fromFrame, int toFrame) { + for (int i = fromFrame; i <= toFrame; i++) { + List aliasList = new ArrayList<>(aliasCollector.getAliasList()); + Alias alias = aliasList.get(i); + System.out.println("\r\n" + i + ": " + alias.getAliasType().toString()); + System.out.println(alias.getObjectId() + ", " + alias.getMethodSignature() + " l." + alias.getLineNo()); + switch(alias.getAliasType()) { + case RETURN_VALUE: + moveObjectVertex(alias); + update(); + break; + case METHOD_INVOCATION: + removeMethodExecutionVertex(alias); + moveObjectVertex(alias); + update(); + break; + case CONSTRACTOR_INVOCATION: + createObjectVertexOnConstractor(alias); + createMethodExecutionVertex(alias.getObjectId(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCallerSideMethodName(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution()); + update(); + removeMethodExecutionVertex(alias); + update(); + break; + case FORMAL_PARAMETER: + moveObjectVertex(alias); + update(); + break; + case ACTUAL_ARGUMENT: + moveObjectVertex(alias); + update(); + break; + case THIS: + if (curFrame == 0 || alias.getObjectId().matches("0")) { + createMethodExecutionVertex(alias); + update(); + } + break; + case RECEIVER: + // Make VertexMethodExecution of called method execution. + MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + if (!methodExecToVertexMap.containsKey(calledMethodExec)) { + if (curFrame == 0) { + MethodExecution methodExec = alias.getMethodExecution(); + if (methodExec.getSignature() != calledMethodExec.getSignature() && objectToVertexMap.containsKey(methodExec.getThisObjId())) { + createMethodExecutionVertex(methodExec.getThisObjId(), methodExec.getSignature(), methodExec); + } + } + createMethodExecutionVertex(alias.getObjectId(), calledMethodExec.getSignature(), calledMethodExec); + update(); + } + break; + default: + break; + } + curFrame = i + 1; + outputLog(); + } + } + + /** + * Create ObjectVertex when CONSTRACTOR_INVOCATION. + * @param alias + */ + protected void createObjectVertexOnConstractor(Alias alias) { + ObjectVertex objectVertex = objectToVertexMap.get(alias.getObjectId()); + String sourceObjId = alias.getMethodExecution().getThisObjId(); + mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjId).getCell(); + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth * Math.sqrt(2) * 0.1; + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + MethodInvocation methodInvocation; + String fieldName = null; + if (!alias.getMethodExecution().isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { + methodInvocation = (MethodInvocation)alias.getOccurrencePoint().getStatement(); + fieldName = methodInvocation.getCallerSideMethodName(); + } + Point absPtSrcCell = getAbsolutePointforCell(sourceCell); + mxgraph.getModel().beginUpdate(); + try { + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + objectVertex.setCell(vertex); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, sourceCell, vertex); + setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); + edgeMap.put(alias.getMethodExecution().getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); + setCellsStyle(); + deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); + deltaAnimation.startVertexAnimation(); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Create ObjectVertex when CONSTRACTOR_INVOCATION is preceded by FORMAL_PARAMETER. + * @param alias + */ + protected void createObjectVertexOnConstractorByFormalParameter(Alias alias) { + ObjectVertex objectVertex = objectToVertexMap.get(alias.getObjectId()); // Create cell of this object vertex. + MethodExecution methodExec = alias.getMethodExecution(); + String srcObjId = methodExec.getArguments().get(0).getId(); + mxICell srcCell = (mxICell)objectToVertexMap.get(srcObjId).getCell(); + double srcWidth = srcCell.getGeometry().getWidth(); + double srcHeight = srcCell.getGeometry().getHeight(); + double overlapWidth = srcWidth * Math.sqrt(2) * 0.1; + double overlapHeight = srcHeight - (srcHeight * Math.sqrt(2) * 0.1); + Point absPtSrcCell = getAbsolutePointforCell(srcCell); + MethodInvocation methodInv; + String fieldName = null; + if (!methodExec.isCollectionType() && alias.getOccurrencePoint().getStatement() != null) { + methodInv = (MethodInvocation)alias.getOccurrencePoint().getStatement(); + fieldName = methodInv.getCallerSideMethodName(); + } + mxgraph.getModel().beginUpdate(); + try { + Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, objectVertex.getLabel(), objectVertex.getLabel(), absPtSrcCell.getX() + overlapWidth, absPtSrcCell.getY() + overlapHeight, VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex. + objectVertex.setCell(vertex); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldName, null, srcCell, vertex); + setEdgePoint((mxCell)edge, absPtSrcCell, objectVertex.getInitialPoint()); + edgeMap.put(methodExec.getThisClassName() + "." + fieldName, new Edge(fieldName, TypeName.Create, edge)); + setCellsStyle(); + deltaAnimation.setVertexAnimation((mxICell)vertex, new mxPoint(objectVertex.getInitialX(), objectVertex.getInitialY())); + deltaAnimation.startVertexAnimation(); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + protected void createObjectRefrence(FieldUpdate fieldUpdateStatement, String fieldName) { + String sourceObjectId = fieldUpdateStatement.getContainerObjId(); + String targetObjectId = fieldUpdateStatement.getValueObjId(); + mxICell sourceCell = (mxICell)objectToVertexMap.get(sourceObjectId).getCell(); + mxICell targetCell = (mxICell)objectToVertexMap.get(targetObjectId).getCell(); + Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); + + targetCell.getParent().remove(targetCell); + targetCell.setParent(mxDefaultParent); + targetCell.getGeometry().setX(absolutePointTargetCell.getX()); + targetCell.getGeometry().setY(absolutePointTargetCell.getY()); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, fieldUpdateStatement.getFieldName(), fieldName, objectToVertexMap.get(sourceObjectId).getCell(), objectToVertexMap.get(targetObjectId).getCell()); + ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;"); + edgeMap.put(fieldUpdateStatement.getFieldName(), new Edge(fieldName, TypeName.Reference, edge)); + // System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); + deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(targetObjectId).getInitialX(), objectToVertexMap.get(targetObjectId).getInitialY())); + deltaAnimation.startVertexAnimation(); + targetCell.getGeometry().setX(objectToVertexMap.get(targetObjectId).getInitialX()); + targetCell.getGeometry().setY(objectToVertexMap.get(targetObjectId).getInitialY()); + } + + protected void createObjectRefrence(String srcClassName, String srcObjId, String tgtObjId) { + mxICell targetCell; +// if (objectToVertexMap.containsKey(targetObjId)) { + targetCell = (mxICell)objectToVertexMap.get(tgtObjId).getCell(); +// } else { +// targetObjId = methodExec.getCallerMethodExecution().getArguments().get(0).getId(); +// targetCell = (mxICell)objectToVertexMap.get(targetObjId).getCell(); +// } + Point absolutePointTargetCell = getAbsolutePointforCell(targetCell); + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + targetCell.getParent().remove(targetCell); + targetCell.setParent(mxDefaultParent); + targetCell.getGeometry().setX(absolutePointTargetCell.getX()); + targetCell.getGeometry().setY(absolutePointTargetCell.getY()); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, tgtObjId, null, objectToVertexMap.get(srcObjId).getCell(), objectToVertexMap.get(tgtObjId).getCell()); + ((mxCell)edge).setStyle("exitX=0;exitY=0.5;exitPerimeter=1;entryX=1;entryY=0.5;entryPerimeter=1;"); + edgeMap.put(tgtObjId, new Edge(null, TypeName.Reference, edge)); +// System.out.println("last" + objectToVertexMap.get(targetObjectId).getInitialX() + ", " + objectToVertexMap.get(targetObjectId).getInitialY()); + deltaAnimation.setVertexAnimation(targetCell, new mxPoint(objectToVertexMap.get(tgtObjId).getInitialX(), objectToVertexMap.get(tgtObjId).getInitialY())); + deltaAnimation.startVertexAnimation(); + targetCell.getGeometry().setX(objectToVertexMap.get(tgtObjId).getInitialX()); + targetCell.getGeometry().setY(objectToVertexMap.get(tgtObjId).getInitialY()); + } finally { + mxgraph.getModel().endUpdate(); + } + + System.out.println("rTHIS " + srcClassName + ", " + tgtObjId); + } + + /** + * SourceVertex move targetVertex. + * + * @param alias + */ + protected void moveObjectVertex(Alias alias) { + // sourceVertex + ObjectVertex sourceObjectVertex = objectToVertexMap.get(alias.getObjectId()); + if (alias.getMethodExecution().isStatic() && !methodExecToVertexMap.containsKey(alias.getMethodExecution())) { + createMethodExecutionVertex(alias.getObjectId(), alias.getMethodExecution().getSignature(), alias.getMethodExecution()); + } + // targetVertex + MethodExecutionVertex targetMethodExecVertex = methodExecToVertexMap.get(alias.getMethodExecution()); + System.out.println("moveObjectVertex: " + targetMethodExecVertex); + System.out.println("moveObjectVertex: " + alias.getMethodExecution().isStatic()); + moveObjectVertex(alias, sourceObjectVertex, targetMethodExecVertex); + updateObjectVertices(); + } + + /** + * Parent : Source VertexObject move target VertexMethodExecution. + * + * @param alias + * @param sourceVertexObject Source VertexObject. + * @param targetVertexMethodExec Target VertexMethodExecution. + */ + private void moveObjectVertex(Alias alias, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { + MethodExecution methodExec = alias.getMethodExecution(); + if (alias.getAliasType().equals(AliasType.RETURN_VALUE) || alias.getAliasType().equals(AliasType.METHOD_INVOCATION)) { + if (sourceVertexObject.getCell() == null && methodExec.isCollectionType()) { + if (methodExec.getArguments().isEmpty()) { + createObjectVertexOnConstractor(alias); + } else { + createObjectVertexOnConstractorByFormalParameter(alias); + } + } + moveLocalObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } else if (alias.getAliasType().equals(AliasType.FORMAL_PARAMETER)) { + moveArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } else if (alias.getAliasType().equals(AliasType.ACTUAL_ARGUMENT)) { + moveActualArgumentObjectVertex(methodExec, sourceVertexObject, targetVertexMethodExec); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Local position from caller MethodExecution. + * + * @param callerMethodExec Caller MethodExecution. + * @param sourceVertexObject + * @param targetVertexMethodExec + */ + private void moveLocalObjectVertex(MethodExecution callerMethodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); + + if (sourceCell == targetCell.getParent()) { + System.out.println("nothing."); + return; + } + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExec).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(callerMethodExec) && methodExecToVertexMap.get(callerMethodExec).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExec).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + int time = targetVertexMethodExec.getLocals().size(); + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + // System.out.println(time); + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + System.out.println("moveLocalObjectVertex: " + sourceCell.getId() + " (" + sourceCell.hashCode() + ")" + ", " + sourceCell.getParent().getId() + " (" + sourceCell.getParent().hashCode() + ")"); + System.out.println(" " + targetCell.getId() + " (" + targetCell.hashCode() + ")" + ", " + targetCell.getParent().getId() + " (" + targetCell.getParent().hashCode() + ")"); + + Point absolutePointTargetCell = getAbsolutePointforCell(sourceCell.getParent()); + sourceCell.getGeometry().setX(sourceX - absolutePointTargetCell.getX()); + sourceCell.getGeometry().setY(sourceY - absolutePointTargetCell.getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double targetWidth = targetCell.getGeometry().getWidth(); + double targetHeight = targetCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + +// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); +// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + sourceHeight)); + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); + deltaAnimation.startVertexAnimation(); + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); +// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); +// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); +// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); +// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + sourceHeight); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(2.5)) + (sourceWidth * time)); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); + targetVertexMethodExec.getLocals().add(sourceVertexObject); + System.out.println("moveLocalObjectVertex: " + targetVertexMethodExec.getLabel() + " :Local: " + sourceVertexObject.getLabel()); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. + * + * @param methodExec MethodExecution. + * @param sourceVertexObject move + * @param targetVertexMethodExec + */ + private void moveArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); + // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + int time = targetVertexMethodExec.getArguments().size(); + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + // System.out.println(time); + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + if (!isParent(targetCell, sourceCell)) { + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); + sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); + sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.startVertexAnimation(); + + // sourceCell.setParent(targetCell.getParent()); + // targetCell.getParent().insert(sourceCell); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + targetVertexMethodExec.getArguments().add(sourceVertexObject); + System.out.println("moveArgumentObejctVertex" + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); + } else { // �d�l��̃o�O, ���[�v������ + outputLog(); +// try { + // ObjectVertex(sourceCell)�̃N���[������ +// mxICell cloneSourceCell = (mxICell) mxgraph.addCell(sourceCell.clone()); +// +// cloneSourceCell.setStyle("fillColor=#ffffff;opacity=50;shape=ellipse"); +// cloneSourceCell.setId("clone" + cloneSourceCell.getId()); +// cloneSourceCell.setValue(null); +// cloneSourceCell.setParent(sourceCell); +// sourceCell.insert(cloneSourceCell); +// cloneSourceCell.getGeometry().setX(0); +// cloneSourceCell.getGeometry().setX(0); +// cloneSourceCell.getGeometry().setY(0); + + // ����ObjectVertex + Point absPtSourceCell = getAbsolutePointforCell(sourceCell); + Point absPtTargetParentCell = getAbsolutePointforCell(targetCell.getParent()); + + sourceCell.remove(targetCell.getParent()); + targetCell.getParent().setParent(mxDefaultParent); + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + + targetCell.getParent().getGeometry().setX(absPtTargetParentCell.getX()); + targetCell.getParent().getGeometry().setY(absPtTargetParentCell.getY()); + sourceCell.getGeometry().setX(absPtSourceCell.getX() - absPtTargetParentCell.getX()); + sourceCell.getGeometry().setY(absPtSourceCell.getY() - absPtTargetParentCell.getY()); + sourceCell.setStyle("opacity=50;shape=ellipse"); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); +// double overlapWidth = targetCell.getGeometry().getWidth() / 2; + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + +// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() + overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time), targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.startVertexAnimation(); + outputLog(); +// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() + overlapWidth); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth + (sourceWidth * time)); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + + targetVertexMethodExec.getArguments().add(sourceVertexObject); + +// } catch (CloneNotSupportedException e) { +// e.printStackTrace(); +// } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** + * Source VertexObject move target VertexMethodExecution to Argument position from MethodExecution. + * + * @param methodExec MethodExecution. + * @param sourceVertexObject + * @param targetVertexMethodExec + */ + private void moveActualArgumentObjectVertex(MethodExecution methodExec, ObjectVertex sourceVertexObject, MethodExecutionVertex targetVertexMethodExec) { + mxICell sourceCell = (mxICell)sourceVertexObject.getCell(); + mxICell targetCell = (mxICell) targetVertexMethodExec.getCell(); + // mxICell parentTargetMethodExecCell = targetMethodExecCell.getParent(); + + if (sourceCell == targetCell.getParent()) { + System.out.println("nothing."); + return; + } + + // Remove sourceVertex from Locals and Arguments Vertex of MethodExecution's Vertex. + // MethodExecution callerMethodExecution = methodExec.getCallerMethodExecution(); + System.out.println(methodExec.getSignature()); + System.out.println(sourceVertexObject.getLabel()); + // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getLocals().contains(sourceVertexObject)) { + // methodExecToVertexMap.get(callerMethodExecution).getLocals().remove(sourceVertexObject); + // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + // } + // + // if (methodExecToVertexMap.containsKey(callerMethodExecution) && methodExecToVertexMap.get(callerMethodExecution).getArguments().contains(sourceVertexObject)) { + // methodExecToVertexMap.get(callerMethodExecution).getArguments().remove(sourceVertexObject); + // System.out.println(methodExecToVertexMap.get(callerMethodExecution).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + // } + if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getLocals().contains(sourceVertexObject)) { + methodExecToVertexMap.get(methodExec).getLocals().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + sourceVertexObject.getLabel()); + } + + if (methodExecToVertexMap.containsKey(methodExec) && methodExecToVertexMap.get(methodExec).getArguments().contains(sourceVertexObject)) { + methodExecToVertexMap.get(methodExec).getArguments().remove(sourceVertexObject); + System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + sourceVertexObject.getLabel()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { +// int time = targetVertexMethodExec.getArguments().size(); +// int time = targetVertexMethodExec.getLocals().size() + 1; + int time = targetVertexMethodExec.getLocals().size(); + double sourceX = sourceCell.getGeometry().getX(); + double sourceY = sourceCell.getGeometry().getY(); + + System.out.println(time + ", " + targetVertexMethodExec.getLocals().size()); + // if (time == 0) time = 1; + + if(sourceCell.getParent().getValue() != null) { + Point absolutePointSourceCell = getAbsolutePointforCell(sourceCell); + sourceX = absolutePointSourceCell.getX(); + sourceY = absolutePointSourceCell.getY(); + sourceCell.getParent().remove(sourceCell); + } + + sourceCell.setParent(targetCell.getParent()); + targetCell.getParent().insert(sourceCell); + Point absolutePointSourceParentCell = getAbsolutePointforCell(sourceCell.getParent()); + sourceCell.getGeometry().setX(sourceX - absolutePointSourceParentCell.getX()); + sourceCell.getGeometry().setY(sourceY - absolutePointSourceParentCell.getY()); + + double sourceWidth = sourceCell.getGeometry().getWidth(); + double sourceHeight = sourceCell.getGeometry().getHeight(); + double targetWidth = targetCell.getGeometry().getWidth(); + double targetHeight = targetCell.getGeometry().getHeight(); + double overlapWidth = sourceWidth - (sourceWidth * Math.sqrt(2) * 0.1); + double overlapHeight = sourceHeight - (sourceHeight * Math.sqrt(2) * 0.1); + +// deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - overlapWidth, targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time))); + deltaAnimation.setVertexAnimation(sourceCell, new mxPoint(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time), targetCell.getGeometry().getY() + targetHeight)); + deltaAnimation.startVertexAnimation(); +// sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - overlapWidth); +// sourceCell.getGeometry().setY(targetCell.getGeometry().getY() - overlapHeight + (sourceHeight * time)); + sourceCell.getGeometry().setX(targetCell.getGeometry().getX() - (sourceWidth / Math.sqrt(3)) + (sourceWidth * time)); + sourceCell.getGeometry().setY(targetCell.getGeometry().getY() + targetHeight); + + targetVertexMethodExec.getArguments().add(sourceVertexObject); + System.out.println("moveActualArgumentObjectVertex: " + targetVertexMethodExec.getLabel() + " :Argument: " + sourceVertexObject.getLabel()); + } finally { + mxgraph.getModel().endUpdate(); + } + } + + /** Update ObjectVertices size and position. */ + protected void updateObjectVertices() { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology + mxgraph.getModel().beginUpdate(); + try { + for (ObjectVertex objectVertex: objectToVertexMap.values()) { + mxCell objectVertexCell = ((mxCell) objectVertex.getCell()); + if (objectVertexCell != null) { + int time = 0; + for (int i = 0; i < objectVertexCell.getChildCount(); i++) { + if (!(objectVertexCell.getChildAt(i).getId()).contains("clone")) { + time++; + } + } + if (time == 0) { + time = 1; + } + if(objectVertexCell.getGeometry().getWidth() != VERTEX_OBJECT_SIZE.getWidth() * time) { + System.out.println("updateVertexObjectSize: " + objectVertexCell.getGeometry().getWidth() + "->" + VERTEX_OBJECT_SIZE.getWidth() * time+ ", " + objectVertexCell.getId()); + Dimension targetDimension = new Dimension(); + targetDimension.setSize(VERTEX_OBJECT_SIZE.getWidth() * time, VERTEX_OBJECT_SIZE.getHeight() * time); + if (objectVertexCell.getParent() != mxDefaultParent && (objectVertexCell.getChildCount() != 0 || objectVertexCell.getGeometry().getWidth() > VERTEX_OBJECT_SIZE.getWidth() * time)) { + double overlapX = (targetDimension.getWidth() - objectVertexCell.getGeometry().getWidth()) / 2 / Math.sqrt(2); + double overlapY = (targetDimension.getHeight() - objectVertexCell.getGeometry().getHeight()) / 2 / Math.sqrt(2); + System.out.println("updateVertexObjectPosition: " + objectVertexCell.getGeometry().getX() + " - " + overlapX); + mxPoint targetPoint = new mxPoint(objectVertexCell.getGeometry().getX() - overlapX, objectVertexCell.getGeometry().getY() + overlapY); + for (MethodExecutionVertex methodExecVertex: methodExecToVertexMap.values()) { + List arguments = methodExecVertex.getArguments(); + if (arguments != null && arguments.contains(objectVertex)) { + targetPoint.setY(objectVertexCell.getGeometry().getY() - overlapY); + break; + } + } + deltaAnimation.setVertexAnimation(objectVertexCell, targetPoint); + deltaAnimation.startVertexAnimation(); + } + deltaAnimation.setResizeVertexAnimation(objectVertexCell, targetDimension); + deltaAnimation.startResizeVertexAnimation(); + } + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + } + + abstract public void createMethodExecutionVertex(Alias alias); + + /** + * Parent : Create MethodExecutionVertex. + * + * @param objId + * @param methodSignature Called or this MethodSignature. + * @param methodExec Called or this MethodExecution. + */ + protected void createMethodExecutionVertex(String objId, String methodSignature, MethodExecution methodExec) { + if (methodSignature == null) methodSignature = methodExec.getSignature(); + + if (methodSignature.matches(".+\\(.*\\)")) { + System.out.println(methodSignature); + methodSignature = formatMethodSignature(methodSignature, methodExec.getThisClassName()); + } + + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + if (methodExec.isStatic() && !objId.equals("0")) { + objId = methodExec.getCallerMethodExecution().getThisObjId(); + } + + Object object = objectToVertexMap.get(objId).getCell(); + +// if (object != null) { + double xCor = VERTEX_OBJECT_SIZE.getWidth() * 0.1; + double yCor = VERTEX_OBJECT_SIZE.getHeight() * 0.5; + double standardX = xCor; + double standardY = 0; + int time = objectToVertexMap.get(objId).getVertexMethodExecutions().size(); + System.out.println(time); + if (time >= 1) { + mxICell standardCell = (mxICell) objectToVertexMap.get(objId).getVertexMethodExecutions().get(0).getCell(); + standardX = standardCell.getGeometry().getX(); + standardY = standardCell.getGeometry().getY(); + time-=1; + } + + Object vertex = mxgraph.insertDeltaVertex(object, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. + System.out.println("makeVertexMethodExecution: " + ((mxICell)vertex).getId() + " in " + objId + " (" + standardX + ", " + yCor * (time + 1) + standardY + ")"); + + MethodExecutionVertex vertexMethodExecution = new MethodExecutionVertex(methodSignature, vertex, standardX , yCor * (time + 1) + standardY, VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); + // Object vertex = mxgraph.insertVertex(object, methodSignature, methodSignature, 0, 0, 0, 0, "fillColor=white", true); //creates a white vertex. + // Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, methodSignature, methodSignature, "fillColor=white"); //creates a white vertex. + // VertexMethodExecution vertexMethodExecution = new VertexMethodExecution(methodSignature, vertex, getXForCell(objectId) + (xCor * (time + 1)), getYForCell(objectId) + (yCor * (time + 1)), VERTEX_METHOD_EXECUTION_SIZE.getWidth(), VERTEX_METHOD_EXECUTION_SIZE.getHeight()); + methodExecToVertexMap.put(methodExec, vertexMethodExecution); + if(methodExecToVertexMap.size() > 1) { + ((mxICell)vertex).setVisible(false); + createEdgeToMethodExecution(); + } + objectToVertexMap.get(objId).addMethodExecution(vertexMethodExecution); +// } + } finally { + mxgraph.getModel().endUpdate(); + } + setCellsStyle(); + } + + /** + * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param alias + */ + private void removeMethodExecutionVertex(Alias alias) { + // sourceVertex + ObjectVertex sourceVertexObject = objectToVertexMap.get(alias.getObjectId()); + MethodExecution methodExec = alias.getMethodExecution(); + + if(alias.getAliasType().equals(AliasType.METHOD_INVOCATION) || alias.getAliasType().equals(AliasType.CONSTRACTOR_INVOCATION)) { + MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + List arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); + List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); + if (arguments.size() != 0) { + for (ObjectVertex vo: arguments) { + if (vo != sourceVertexObject) { + System.out.println("argumentRemove"); + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + methodExecToVertexMap.get(calledMethodExec).getArguments().remove(vo); + } + } + } + if (locals.size() != 0) { + for (ObjectVertex vo: locals) { + if (vo != sourceVertexObject) { + System.out.println("localRemove"); + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); + } + } + } + } finally { + mxgraph.getModel().endUpdate(); + } + + + removeCalledMethodExecutionVertex(sourceVertexObject, methodExec, calledMethodExec); + } else { + removeMethodExecutionVertex(sourceVertexObject, methodExec); + } + } + + /** + * Remove VertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param sourceVertexObject + * @param methodExec + */ + private void removeMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec) { + // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(methodExec)) { + mxCell targetVertexCell = (mxCell)methodExecToVertexMap.get(methodExec).getCell(); + targetVertexCell.getParent().remove(targetVertexCell); + targetVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {targetVertexCell}); + objectToVertexMap.get(methodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(methodExec)); + methodExecToVertexMap.remove(methodExec); + edgeMap.remove(methodExec.getSignature()); + updateObjectVertices(); + } + } + + /** + * Remove CalledVertexMethodExecution on AliasType is MethodInvocation of alias. + * + * @param sourceVertexObject + * @param methodExec + * @param calledMethodExec + */ + protected void removeCalledMethodExecutionVertex(ObjectVertex sourceVertexObject, MethodExecution methodExec, MethodExecution calledMethodExec) { + outputLog(); + + // Remove sourceVertex from Locals and Arguments Vertex of CalledMethodExecution's Vertex. + if (methodExecToVertexMap.containsKey(calledMethodExec)) { + mxICell sourceVertexCell = null; + mxCell targetVertexCell = null; + + if (methodExec != null) { + sourceVertexCell = (mxICell)methodExecToVertexMap.get(methodExec).getCell(); + targetVertexCell = (mxCell)methodExecToVertexMap.get(calledMethodExec).getCell(); + } +// if(!calledMethodExec.isStatic()) { + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. + mxgraph.getModel().beginUpdate(); + try { + // Dangerous + List arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); + List locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); + if (arguments.size() != 0) { + for (ObjectVertex vo: arguments) { + if (vo != sourceVertexObject) { + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + System.out.println(cell); + System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); + System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); + System.out.println(absolutePointCell); + if (cell.getParent() != mxDefaultParent) { + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + } + if (!absolutePointCell.equals(vo.getInitialPoint())) { + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + } + methodExecToVertexMap.get(calledMethodExec).getArguments().remove(vo); + } + } + } + if (locals.size() != 0) { + for (ObjectVertex vo: locals) { + if (vo != sourceVertexObject) { + mxICell cell = (mxICell)vo.getCell(); + Point absolutePointCell = getAbsolutePointforCell(cell); + System.out.println(cell); + System.out.println(vo.getInitialX() + ", " + vo.getInitialY()); + System.out.println(cell.getGeometry().getX() + ", " + cell.getGeometry().getY()); + System.out.println(absolutePointCell); + if (cell.getParent() != mxDefaultParent) { + cell.getParent().remove(cell); + cell.setParent(mxDefaultParent); + } + if (!absolutePointCell.equals(vo.getInitialPoint())) { + cell.getGeometry().setX(absolutePointCell.getX()); + cell.getGeometry().setY(absolutePointCell.getY()); + deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY())); + deltaAnimation.startVertexAnimation(); + } + methodExecToVertexMap.get(calledMethodExec).getLocals().remove(vo); + } + } + } + + if (sourceVertexCell == null || targetVertexCell == null) return; + + mxgraph.removeCells(mxgraph.getEdgesBetween(sourceVertexCell, targetVertexCell)); + try { + mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); + Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); + Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); + cloneTargetVertexCell.getGeometry().setX(absolutPointTargetVertexCell.getX()); + cloneTargetVertexCell.getGeometry().setY(absolutPointTargetVertexCell.getY()); + cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); + cloneTargetVertexCell.setValue(null); + Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); + ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); + deltaAnimation.setReductionEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointSourceVertexCell.getX(), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight())); + deltaAnimation.startReductionEdgeAnimation(); +// deltaAnimation.setReductionEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); +// deltaAnimation.startReductionEdgeAnimation(); + mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } finally { + mxgraph.getModel().endUpdate(); + } + ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); + targetVertexCell.setParent(mxDefaultParent); + mxgraph.removeCells(new Object[] {targetVertexCell}); + if (!calledMethodExec.isStatic()) { + objectToVertexMap.get(calledMethodExec.getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); + } else { + objectToVertexMap.get(calledMethodExec.getCallerMethodExecution().getThisObjId()).getVertexMethodExecutions().remove(methodExecToVertexMap.get(calledMethodExec)); + } + methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); + methodExecToVertexMap.remove(calledMethodExec); + edgeMap.remove(methodExec.getSignature()); +// moveInitialVertexObject(methodExec); +// updateObjectVerticesSize(); +// } else { +// ((mxCell)targetVertexCell.getParent()).remove(targetVertexCell); +// targetVertexCell.setParent(mxDefaultParent); +// mxgraph.removeCells(new Object[] {targetVertexCell}); +// methodExecToVertexMap.get(calledMethodExec).getLocals().remove(sourceVertexObject); +// methodExecToVertexMap.remove(calledMethodExec); +// } + } + outputLog(); + } + + /** Make EdgeMethodExecution. */ + private void createEdgeToMethodExecution() { + List methodExecList = new ArrayList<>(methodExecToVertexMap.keySet()); + + // BUG : Edge Orientation Reverse. + for (int i = 0; i < methodExecList.size() - 1; i++) { + MethodExecution sourceMethodExec = methodExecList.get(i); + MethodExecution targetMethodExec = methodExecList.get(i + 1); + String methodSignature = sourceMethodExec.getSignature(); + if (!edgeMap.containsKey(methodSignature)) { + mxICell sourceVertexCell = (mxICell)methodExecToVertexMap.get(sourceMethodExec).getCell(); + mxICell targetVertexCell = (mxICell)methodExecToVertexMap.get(targetMethodExec).getCell(); +// if (!targetMethodExec.isStatic()) { + Point absolutPointSourceVertexCell = getAbsolutePointforCell(sourceVertexCell); + Point absolutPointTargetVertexCell = getAbsolutePointforCell(targetVertexCell); + // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology + mxgraph.getModel().beginUpdate(); + try { + try { + mxICell cloneTargetVertexCell = (mxICell) mxgraph.addCell(targetVertexCell.clone()); + cloneTargetVertexCell.getGeometry().setX(absolutPointSourceVertexCell.getX()); + cloneTargetVertexCell.getGeometry().setY(absolutPointSourceVertexCell.getY() + targetVertexCell.getGeometry().getHeight()); + cloneTargetVertexCell.setStyle("fillColor=none;strokeColor=none;fontColor=#008000;"); + cloneTargetVertexCell.setValue(null); + cloneTargetVertexCell.setVisible(true); + Object tempEdge = mxgraph.insertEdge(mxDefaultParent, null, null, sourceVertexCell, cloneTargetVertexCell); + ((mxCell)tempEdge).setStyle("dashed=1;strokeColor=#008000;exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;endArrow=none"); + deltaAnimation.setExpandEdgeAnimation(cloneTargetVertexCell, new mxPoint(absolutPointTargetVertexCell.getX(), absolutPointTargetVertexCell.getY())); + deltaAnimation.startExpandEdgeAnimation(); + targetVertexCell.setVisible(true); +// deltaAnimation.setExpandEdgeAnimation(new mxPoint(absolutPointSourceVertexCell.getX() + (sourceVertexCell.getGeometry().getWidth() / 2), absolutPointSourceVertexCell.getY() + sourceVertexCell.getGeometry().getHeight()), new mxPoint(absolutPointTargetVertexCell.getX() + (targetVertexCell.getGeometry().getWidth() / 2), absolutPointTargetVertexCell.getY())); +// deltaAnimation.startExpandEdgeAnimation(); + Object edge = mxgraph.insertDeltaEdge(mxDefaultParent, methodSignature, null, sourceVertexCell, targetVertexCell); + ((mxCell)edge).getParent().remove(((mxCell)edge)); + ((mxCell)edge).setParent(mxDefaultParent); + mxgraph.orderCells(false, new Object[] {edge}); + ((mxCell)edge).setStyle("exitX=0.5;exitY=1;exitPerimeter=1;entryX=0.5;entryY=0;entryPerimeter=1;"); + mxgraph.removeCells(new Object[]{cloneTargetVertexCell}); + edgeMap.put(methodSignature, new Edge(methodSignature, TypeName.Call, edge)); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } finally { + mxgraph.getModel().endUpdate(); + } +// } else { +// targetVertexCell.setVisible(true); +// } + + } + } + } + + protected void setEdgePoint(mxICell edge, Point absPtSrcCell, Point absPtTgtCell) { + if(absPtSrcCell.getX() < absPtTgtCell.getX()) { + // if(isSrcSideChanged) { + // �E�����獶��փG�b�W������ + edge.setStyle("exitX=1;exitY=1;exitPerimeter=1;entryX=0;entryY=0;entryPerimeter=1;"); + } else { + // ��������E��փG�b�W������ + edge.setStyle("exitX=0;exitY=1;exitPerimeter=1;entryX=1;entryY=0;entryPerimeter=1;"); + } + } + /** Set style of All cells. */ protected void setCellsStyle() { List vertexObject = new ArrayList<>(); @@ -74,7 +982,7 @@ List edgeObjectCreate = new ArrayList<>(); List edgeMethodExec = new ArrayList<>(); List roundEdge = new ArrayList<>(); - + for (Entry objectToVertexEntry: objectToVertexMap.entrySet()) { String key = objectToVertexEntry.getKey(); ObjectVertex objectVertex = objectToVertexEntry.getValue(); @@ -89,7 +997,7 @@ alignTopVertex.add(objectVertex.getCell()); } } - + List vertexMethodExecList = new ArrayList<>(methodExecToVertexMap.values()); Collections.reverse(vertexMethodExecList); for (int i = 0; i < vertexMethodExecList.size(); i++) { @@ -113,7 +1021,7 @@ break; } } - + for (Edge edge: edgeMap.values()) { roundEdge.add(edge.getCell()); switch(edge.getTypeName()) { @@ -131,7 +1039,7 @@ break; } } - + /*Given a cell, we can change it's style attributes, for example the color. NOTE that you have to call the graphComponent.refresh() function, otherwise you won't see the difference! */ mxgraph.setCellStyles(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); mxgraph.setCellStyles(mxConstants.STYLE_PERIMETER, mxConstants.PERIMETER_ELLIPSE, vertexObject.toArray(new Object[vertexObject.size()])); @@ -153,21 +1061,19 @@ // mxgraph.setCellStyles(mxConstants.STYLE_ELBOW, mxConstants.ELBOW_VERTICAL, edgeMethodExec.toArray(new Object[edgeMethodExec.size()])); } - abstract public void initAnimation(); + private void setFrameSize(int width, int height) { + DEFAULT_SIZE.setSize(width, height); + } - /** - * Step to animation of specified alias. - * - * @param alias Alias type and occurrence point etc. - */ - abstract public void stepToAnimation(Alias alias); - - /** - * Parent : Step to animation of specified numFrame. - * - * @param numFrame Current animation frame. - */ - abstract public void stepToAnimation(int numFrame); + protected Point getAbsolutePointforCell(mxICell cell) { + Point p1 = cell.getGeometry().getPoint(); + if(cell.getParent().getValue() == null || cell == cell.getParent()) { + return p1; + } + System.out.println(cell.getId() + ", " + cell.getParent().getId()); + Point p2 = getAbsolutePointforCell(cell.getParent()); + return new Point((int) (p1.getX() + p2.getX()), (int) (p1.getY() + p2.getY())); + } /** Update graph on JFrame and set Cell style. */ protected void update() { @@ -180,8 +1086,111 @@ } } - protected void setFrameSize(int width, int height) { - DEFAULT_SIZE.setSize(width, height); + private int countChildVertex(ObjectVertex vertexObject) { + int time = vertexObject.getVertexMethodExecutions().size(); + if(time == 0) { + return 1; + } + for(MethodExecutionVertex vertexMethodExecution: vertexObject.getVertexMethodExecutions()) { + for(ObjectVertex vo: vertexMethodExecution.getLocals()) { + time += countChildVertex(vo); + } + for(ObjectVertex vo: vertexMethodExecution.getArguments()) { + return countChildVertex(vo); + } + } + System.out.println(vertexObject.getLabel() + ": " + time); + return time; + } + + protected String[] formatFieldName(String fieldName) { + String fieldNames[] = fieldName.split("\\."); + String names[] = new String[] {fieldNames[0], fieldNames[fieldNames.length - 1]}; + for(int i = 1; i < fieldNames.length - 1; i++) { + names[0] += "." + fieldNames[i]; + } + return names; + } + + protected String formatMethodSignature(String methodSignature, String thisClassName) { + // Step1 : split "(" + String[] methodSignatures = methodSignature.split("\\("); + methodSignature = methodSignatures[0]; + // Step2 : split " " + methodSignatures = methodSignature.split(" "); + String tmpMethodSignature = methodSignatures[methodSignatures.length-1]; + // Step2 : split "." + String[] thisClassNames = thisClassName.split("\\."); + methodSignatures = tmpMethodSignature.split("\\."); + StringBuffer sb = new StringBuffer(); + int i = methodSignatures.length - 2; + if (i >= 0 && !thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i])) { + if (thisClassNames[thisClassNames.length - 1].equals(methodSignatures[i + 1])) i += 1; + sb.append(methodSignatures[i]); + if (methodSignatures.length - i > 1) sb.append("."); + } + for (i = i + 1; i < methodSignatures.length; i++) { + sb.append(methodSignatures[i]); + if (methodSignatures.length - i > 1) sb.append("."); + } + sb.append("()"); + + String newMethodSignature = sb.toString(); + if (!newMethodSignature.isEmpty()) { + return newMethodSignature; + } + return methodSignature; + } + + protected String formatArrayName(String srcClassName) { + // Step1 : remove "[L" + StringBuffer sb = new StringBuffer(); + sb.append(srcClassName.substring(2, srcClassName.length()-1)); + sb.append("[]"); + return sb.toString(); + } + + protected String formatArrayIndex(int index) { + StringBuffer sb = new StringBuffer(); + sb.append("["); + sb.append(index); + sb.append("]"); + return sb.toString(); + } + + protected void outputLog() { + for (Object object: mxgraph.getChildCells(mxDefaultParent)) { + System.out.println(object + " " + object.hashCode()); + for (int i = 0; i < ((mxICell)object).getChildCount(); i++) { + System.out.println(" " + ((mxICell)object).getChildAt(i) + " " + object.hashCode()); + } + } + System.out.println("\nObject"); + for (Entry e: objectToVertexMap.entrySet()) { + String objId = e.getKey(); + ObjectVertex vo = e.getValue(); + if (vo.getCell() != null) { + System.out.println(vo.getLabel() + " (" + objId + ")" + " " + vo.getCell().hashCode()); + } else { + System.out.println(vo.getLabel() + " (" + objId + ")"); + } + for (MethodExecutionVertex vme: vo.getVertexMethodExecutions()) { + System.out.println(" " + vme.getLabel()); + for (ObjectVertex vmevo: vme.getArguments()) { + System.out.println(" Argument: " + vmevo.getLabel()); + } + for (ObjectVertex vmevo: vme.getLocals()) { + System.out.println(" Local: " + vmevo.getLabel()); + } + } + } + System.out.println("\nEdge"); + for (Edge e: edgeMap.values()) { + System.out.println(e.getLabel() + "(" + ((mxICell)e.getCell()).getId() + ")"); + if (((mxICell)e.getCell()).getParent() != null) { + System.out.println(" " + ((mxICell)e.getCell()).getParent().getId()); + } + } } /** @@ -190,7 +1199,7 @@ * @param targetCell * @return */ - protected boolean isParent(mxICell sourceCell, mxICell targetCell) { + private boolean isParent(mxICell sourceCell, mxICell targetCell) { mxICell sourceParentCell = sourceCell.getParent(); if (sourceParentCell == null || sourceParentCell.getValue() == null) { return false; @@ -202,16 +1211,6 @@ return isParent(sourceParentCell, targetCell); } - protected Point getAbsolutePointforCell(mxICell cell) { - Point p1 = cell.getGeometry().getPoint(); - if(cell.getParent().getValue() == null || cell == cell.getParent()) { - return p1; - } - System.out.println(cell.getId() + ", " + cell.getParent().getId()); - Point p2 = getAbsolutePointforCell(cell.getParent()); - return new Point((int) (p1.getX() + p2.getX()), (int) (p1.getY() + p2.getY())); - } - protected void reflectCoordinates(DeltaGraphAdapter mxgraph) { // TODO Auto-generated method stub } diff --git a/src/tests/CollaborationViewerSampleTest.java b/src/tests/CollaborationViewerSampleTest.java new file mode 100644 index 0000000..e8b6d73 --- /dev/null +++ b/src/tests/CollaborationViewerSampleTest.java @@ -0,0 +1,15 @@ +package tests; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class CollaborationViewerSampleTest { + + public static void main(String[] args) { + // Build a frame, create a graph, and add the graph to the frame so you can actually see the graph. + MagnetRONFrameTest frame = new MagnetRONFrameTest(true); + frame.setVisible(true); + frame.startAnimation(); + } +} diff --git a/src/tests/MagnetRONFrameTest.java b/src/tests/MagnetRONFrameTest.java index 96b8ef8..0492327 100644 --- a/src/tests/MagnetRONFrameTest.java +++ b/src/tests/MagnetRONFrameTest.java @@ -2,17 +2,27 @@ import static org.junit.jupiter.api.Assertions.*; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.HeadlessException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.swing.JFrame; + import org.junit.jupiter.api.Test; +import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.DeltaExtractorJSON; import org.ntlab.deltaExtractor.ExtractedStructure; import org.ntlab.deltaExtractor.IAliasCollector; import org.ntlab.deltaExtractor.IAliasTracker; +import org.ntlab.deltaViewer.CollaborationAliasCollector; +import org.ntlab.deltaViewer.CollaborationLayout; +import org.ntlab.deltaViewer.CollaborationObjectCallGraph; +import org.ntlab.deltaViewer.CollaborationViewer; import org.ntlab.deltaViewer.DeltaAliasCollector; import org.ntlab.trace.MethodExecution; import org.ntlab.trace.ObjectReference; @@ -21,14 +31,63 @@ import org.ntlab.trace.TraceJSON; import org.ntlab.trace.TracePoint; -class MagnetRONFrameTest { +class MagnetRONFrameTest extends JFrame { // Delta Extract Type protected static final String CONTAINER_COMPONENT = "Container-Component"; protected static final String CONTAINER_COMPONENT_COLLECTION = "Container-Component(Collection)"; + private static Dimension DEFAULT_SIZE = new Dimension(1300, 700); + private static String WINDOW_TITLE = "Delta Viewer"; + + private CollaborationViewer viewer = null; + private boolean visible = false; public MagnetRONFrameTest() { } + + public MagnetRONFrameTest(boolean visible) throws HeadlessException { + super(WINDOW_TITLE); + setSize(DEFAULT_SIZE); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setLayout(new BorderLayout()); + this.viewer = new CollaborationViewer(); + getContentPane().add(viewer, BorderLayout.CENTER); + pack(); + this.visible = true; + } + + public void startAnimation() { + if (visible) { + // Change Here! +// String key = "getterOverlap"; + String key = "setterOverlap"; + Map extractedPluralDelta = extractPluralDelta(key); + List eList = new ArrayList<>(extractedPluralDelta.keySet()); + List dacList = new ArrayList<>(extractedPluralDelta.values()); + CollaborationObjectCallGraph cocg = null; + CollaborationAliasCollector cac = null; + for (ExtractedStructure e: eList) { + if (cocg == null) { + cocg = new CollaborationObjectCallGraph(e); + } else { + cocg.merge(e); + } + } + for (IAliasCollector dac: dacList) { + if (cac == null) { + cac = new CollaborationAliasCollector(dac); + } else { + cac.merge(dac); + } + } + +// new Thread() { +// public void run() { + startCollectionViewer(cocg, cac); +// } +// }.start(); + } + } public Map extractPluralDelta(String key) { Map extractedPluralDelta = new HashMap<>(); @@ -89,6 +148,23 @@ return extractedPluralDelta; } + public void startCollectionViewer(CollaborationObjectCallGraph cocg, IAliasCollector cac) { + List aliasList = new ArrayList<>(cac.getAliasList()); + if(cocg != null) { + List relatedPoints = cocg.getRelatedPoints(); + TracePoint relatedPoint = relatedPoints.get(relatedPoints.size()-1); +// if (srcSide.size() >= 1 && dstSide.size() >= 1) { +// WINDOW_TITLE = "extract delta of:" + e.getDelta().getSrcSide().get(0).getDstClassName() + "(" + e.getDelta().getSrcSide().get(0).getDstObjectId() + ")" + " -> " + e.getDelta().getDstSide().get(0).getDstClassName() + "(" + e.getDelta().getDstSide().get(0).getDstObjectId() + ")"; +// setTitle(WINDOW_TITLE); +// } + } + viewer.init(cocg, cac, new CollaborationLayout()); + viewer.initAnimation(); + for (int i = 0; i <= aliasList.size(); i++) { + viewer.stepToAnimation(i); + } + } + private void setArgmentsForDeltaExtract(Map map){ // Samples of Plural Delta String[] getterOverlap1 = {null, null, "getterOverlap.F","getterOverlap.D", "traces/getterOverlap.txt", CONTAINER_COMPONENT_COLLECTION}; map.put("getterOverlap1", getterOverlap1);