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(); + } + } + } } }