| |
---|
| | |
---|
| | // Test code (will be deleted) |
---|
| | private static final String TAG = MagnetRONViewer.class.getSimpleName(); |
---|
| | |
---|
| | protected static final Dimension DEFAULT_COMPONENT_SIZE = new Dimension(1300, 700); |
---|
| | protected static final Dimension DEFAULT_COMPONENT_SIZE = new Dimension(1300, 600); |
---|
| | |
---|
| | protected static final Dimension DEFAULT_OBJECT_VERTEX_SIZE = new Dimension(70, 70); |
---|
| | protected static final Dimension DEFAULT_METHOD_EXECUTION_VERTEX_SIZE = new Dimension(55, 20); |
---|
| | |
---|
| |
---|
| | protected DeltaGraphAdapter mxgraph; |
---|
| | protected mxICell defaultParent; |
---|
| | |
---|
| | protected int curFrame = 0; |
---|
| | protected int prevFrame = 0; |
---|
| | protected int skipBackFrame = 0; // Use assigned value, when skip back animation. |
---|
| | |
---|
| | protected double animationSpeed = DEFAULT_ANIMATION_SPEED; |
---|
| | protected static final double DEFAULT_ANIMATION_SPEED = 1.0; |
---|
| |
---|
| | public mxInteractiveCanvas createCanvas() { |
---|
| | return new CurvedCanvas(this); |
---|
| | } |
---|
| | }; |
---|
| | mxgraphComponent.setPreferredSize(DEFAULT_COMPONENT_SIZE); |
---|
| | mxgraphComponent.setPreferredSize(DEFAULT_COMPONENT_SIZE); |
---|
| | this.setLayout(new BorderLayout()); |
---|
| | this.add(mxgraphComponent, BorderLayout.CENTER); |
---|
| | |
---|
| | this.threadPoolExecutor = new MagnetRONScheduledThreadPoolExecutor(2); |
---|
| |
---|
| | // Test code (will be deleted) |
---|
| | System.out.println("\r\n" + TAG + ": Frame=" + i + ", aliasType=" + alias.getAliasType().toString() + ", objectId=" + alias.getObjectId() + ", methodSignature=" + alias.getMethodSignature() + ", l." + alias.getLineNo()); |
---|
| | switch(alias.getAliasType()) { |
---|
| | case RETURN_VALUE: |
---|
| | prevFrame = curFrame; |
---|
| | moveObjectVertex(alias); |
---|
| | update(); |
---|
| | break; |
---|
| | case METHOD_INVOCATION: |
---|
| | prevFrame = curFrame; |
---|
| | removeMethodExecutionVertex(alias); |
---|
| | moveObjectVertex(alias); |
---|
| | update(); |
---|
| | break; |
---|
| | case CONSTRACTOR_INVOCATION: |
---|
| | prevFrame = curFrame; |
---|
| | // TODO: Confirm the program behavior when called after RECEIVER. |
---|
| | if (!objectToVertexMap.containsKey(alias.getObjectId()) || objectToVertexMap.get(alias.getObjectId()).getCell() == null) { |
---|
| | MethodInvocation methodInv = (MethodInvocation) alias.getOccurrencePoint().getStatement(); |
---|
| | String objId = alias.getObjectId(); |
---|
| | if (!objectToVertexMap.containsKey(objId) || objectToVertexMap.get(objId).getCell() == null) { |
---|
| | createObjectVertexOnConstractor(alias); |
---|
| | } |
---|
| | if (!methodExecToVertexMap.containsKey(((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution())) { |
---|
| | createMethodExecutionVertex(alias.getObjectId(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCallerSideMethodName(), ((MethodInvocation)alias.getOccurrencePoint().getStatement()).getCalledMethodExecution()); |
---|
| | if (!methodExecToVertexMap.containsKey(methodInv.getCalledMethodExecution())) { |
---|
| | createMethodExecutionVertex(objId, methodInv.getCallerSideMethodName(), methodInv.getCalledMethodExecution()); |
---|
| | update(); |
---|
| | } |
---|
| | removeMethodExecutionVertex(alias); |
---|
| | update(); |
---|
| | break; |
---|
| | case FORMAL_PARAMETER: |
---|
| | prevFrame = curFrame; |
---|
| | moveObjectVertex(alias); |
---|
| | update(); |
---|
| | break; |
---|
| | case ACTUAL_ARGUMENT: |
---|
| | prevFrame = curFrame; |
---|
| | moveObjectVertex(alias); |
---|
| | update(); |
---|
| | break; |
---|
| | case THIS: |
---|
| | prevFrame = curFrame; |
---|
| | if (curFrame == 0 || alias.getObjectId().startsWith("0:")) { |
---|
| | createMethodExecutionVertex(alias); |
---|
| | update(); |
---|
| | } |
---|
| |
---|
| | // Make {@code MethodExecutionVertex} of called method execution. |
---|
| | MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); |
---|
| | if (calledMethodExec.isConstructor() |
---|
| | && (!objectToVertexMap.containsKey(alias.getObjectId()) || objectToVertexMap.get(alias.getObjectId()).getCell() == null)) { |
---|
| | prevFrame = curFrame; |
---|
| | createObjectVertexOnConstractor(alias); |
---|
| | } |
---|
| | if (!methodExecToVertexMap.containsKey(calledMethodExec)) { |
---|
| | MethodExecution methodExec = alias.getMethodExecution(); |
---|
| |
---|
| | && methodExec.getSignature() != calledMethodExec.getSignature() |
---|
| | && objectToVertexMap.containsKey(methodExec.getThisObjId())) { |
---|
| | createMethodExecutionVertex(methodExec.getThisObjId(), methodExec.getSignature(), methodExec); |
---|
| | } |
---|
| | prevFrame = curFrame; |
---|
| | createMethodExecutionVertex(alias.getObjectId(), calledMethodExec.getSignature(), calledMethodExec); |
---|
| | update(); |
---|
| | } |
---|
| | break; |
---|
| |
---|
| | */ |
---|
| | private void removeMethodExecutionVertex(Alias alias) { |
---|
| | // source ObjectVertex |
---|
| | ObjectVertex srcObjVx = objectToVertexMap.get(alias.getObjectId()); |
---|
| | AliasType aliasType = alias.getAliasType(); |
---|
| | // Quick fix |
---|
| | if (aliasType == AliasType.CONSTRACTOR_INVOCATION) { |
---|
| | MethodInvocation methodInv = (MethodInvocation) alias.getOccurrencePoint().getStatement(); |
---|
| | List<Statement> statements = methodInv.getCalledMethodExecution().getStatements(); |
---|
| | if (!statements.isEmpty() && statements.get(0) instanceof MethodInvocation) { |
---|
| | MethodInvocation calledMethodInv = (MethodInvocation) statements.get(0); |
---|
| | if (!calledMethodInv.getCalledMethodExecution().getArguments().isEmpty() |
---|
| | && objectToVertexMap.containsKey(calledMethodInv.getCalledMethodExecution().getArguments().get(0).getId())) { |
---|
| | srcObjVx = objectToVertexMap.get(calledMethodInv.getCalledMethodExecution().getArguments().get(0).getId()); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | MethodExecution methodExec = alias.getMethodExecution(); |
---|
| | |
---|
| | AliasType aliasType = alias.getAliasType(); |
---|
| | if(aliasType.equals(AliasType.METHOD_INVOCATION) || aliasType.equals(AliasType.CONSTRACTOR_INVOCATION)) { |
---|
| | MethodExecution calledMethodExec = ((MethodInvocation) alias.getOccurrencePoint().getStatement()).getCalledMethodExecution(); |
---|
| | List<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments()); |
---|
| | List<ObjectVertex> locals = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getLocals()); |
---|
| |
---|
| | * @param calledMethodExec: called method execution |
---|
| | */ |
---|
| | protected void removeCalledMethodExecutionVertex(ObjectVertex sourceObjectVertex, MethodExecution methodExecution, MethodExecution calledMethodExecution) { |
---|
| | MagnetRONAnimation.waitAnimationEnd(); |
---|
| | |
---|
| | |
---|
| | // Remove ObjectVertex other than source ObjectVertex from locals and arguments of called MethodExecutionVertex. |
---|
| | if (methodExecToVertexMap.containsKey(calledMethodExecution)) { |
---|
| | MethodExecutionVertex calledMethodExecVx = methodExecToVertexMap.get(calledMethodExecution); |
---|
| | |
---|
| | // TODO: Confirm bug. |
---|
| | List<ObjectVertex> arguments = new ArrayList<>(calledMethodExecVx.getArguments()); |
---|
| | if (arguments.size() != 0) { |
---|
| | for (ObjectVertex objVx: arguments) { |
---|
| | if (objVx != sourceObjectVertex) { |
---|
| | mxICell objVxCell = (mxICell)objVx.getCell(); |
---|
| | Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell); |
---|
| | // TODO: Confirm bug. |
---|
| | List<ObjectVertex> arguments = new ArrayList<>(calledMethodExecVx.getArguments()); |
---|
| | if (arguments.size() != 0) { |
---|
| | for (ObjectVertex objVx: arguments) { |
---|
| | if (objVx != sourceObjectVertex) { |
---|
| | mxICell objVxCell = (mxICell)objVx.getCell(); |
---|
| | Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell); |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | if (!objVxCell.getParent().equals(getMxDefaultParent())) { |
---|
| | // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent. |
---|
| | objVxCell.getParent().remove(objVxCell); |
---|
| | objVxCell.setParent(getMxDefaultParent()); |
---|
| | } |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | } |
---|
| | if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) { |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | if (!objVxCell.getParent().equals(getMxDefaultParent())) { |
---|
| | // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent. |
---|
| | objVxCell.getParent().remove(objVxCell); |
---|
| | objVxCell.setParent(getMxDefaultParent()); |
---|
| | } |
---|
| | objVxCell.getGeometry().setX(objVxCellAbsPt.getX()); |
---|
| | objVxCell.getGeometry().setY(objVxCellAbsPt.getY()); |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | } |
---|
| | if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) { |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | objVxCell.getGeometry().setX(objVxCellAbsPt.getX()); |
---|
| | objVxCell.getGeometry().setY(objVxCellAbsPt.getY()); |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent()); |
---|
| | objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount()); |
---|
| | objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis()); |
---|
| | objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor); |
---|
| | objVxCellAnim.syncPlay(); |
---|
| | } |
---|
| | methodExecToVertexMap.get(calledMethodExecution).getArguments().remove(objVx); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | List<ObjectVertex> locals = new ArrayList<>(calledMethodExecVx.getLocals()); |
---|
| | if (locals.size() != 0) { |
---|
| | for (ObjectVertex objVx: locals) { |
---|
| | if (objVx != sourceObjectVertex) { |
---|
| | mxICell objVxCell = (mxICell)objVx.getCell(); |
---|
| | Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell); |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | if (!objVxCell.getParent().equals(getMxDefaultParent())) { |
---|
| | // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent. |
---|
| | objVxCell.getParent().remove(objVxCell); |
---|
| | objVxCell.setParent(getMxDefaultParent()); |
---|
| | } |
---|
| | MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent()); |
---|
| | objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount()); |
---|
| | objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis()); |
---|
| | objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor); |
---|
| | objVxCellAnim.syncPlay(); |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | methodExecToVertexMap.get(calledMethodExecution).getArguments().remove(objVx); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | List<ObjectVertex> locals = new ArrayList<>(calledMethodExecVx.getLocals()); |
---|
| | if (locals.size() != 0) { |
---|
| | for (ObjectVertex objVx: locals) { |
---|
| | if (objVx != sourceObjectVertex) { |
---|
| | mxICell objVxCell = (mxICell)objVx.getCell(); |
---|
| | Point2D objVxCellAbsPt = getAbsolutePointforCell(objVxCell); |
---|
| | if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) { |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | if (!objVxCell.getParent().equals(getMxDefaultParent())) { |
---|
| | // If parent of ObjectVertex cell isn't mxDefaltParent, reset parent. |
---|
| | objVxCell.getParent().remove(objVxCell); |
---|
| | objVxCell.setParent(getMxDefaultParent()); |
---|
| | } |
---|
| | objVxCell.getGeometry().setX(objVxCellAbsPt.getX()); |
---|
| | objVxCell.getGeometry().setY(objVxCellAbsPt.getY()); |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | } |
---|
| | if (!objVxCellAbsPt.equals(objVx.getInitialPoint())) { |
---|
| | // Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology. |
---|
| | mxgraph.getModel().beginUpdate(); |
---|
| | synchronized (mxgraph.getModel()) { |
---|
| | try { |
---|
| | objVxCell.getGeometry().setX(objVxCellAbsPt.getX()); |
---|
| | objVxCell.getGeometry().setY(objVxCellAbsPt.getY()); |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | } |
---|
| | MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent()); |
---|
| | objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount()); |
---|
| | objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis()); |
---|
| | objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor); |
---|
| | objVxCellAnim.syncPlay(); |
---|
| | } |
---|
| | methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(objVx); |
---|
| | MagnetRONAnimation objVxCellAnim = new TranslateAnimation(mxgraph, getGraphComponent()); |
---|
| | objVxCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount()); |
---|
| | objVxCellAnim.setDelay(getMagnetRONAnimationDelayMillis()); |
---|
| | objVxCellAnim.init(objVxCell, objVx.getInitialX(), objVx.getInitialY(), threadPoolExecutor); |
---|
| | objVxCellAnim.syncPlay(); |
---|
| | } |
---|
| | methodExecToVertexMap.get(calledMethodExecution).getLocals().remove(objVx); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | if (methodExecution == null) { |
---|
| | } |
---|
| | |
---|
| | // Quick fix |
---|
| | if (methodExecution == null || !methodExecToVertexMap.get(calledMethodExecution).getArguments().isEmpty()) { |
---|
| | return; |
---|
| | } |
---|
| | |
---|
| | |
---|
| | mxICell srcMethodExecVxCell = (mxICell)methodExecToVertexMap.get(methodExecution).getCell(); |
---|
| | mxICell dstMethodExecVxCell = (mxICell)calledMethodExecVx.getCell(); |
---|
| | |
---|
| | |
---|
| | scrollCellsToVisible(srcMethodExecVxCell.getParent(), dstMethodExecVxCell.getParent()); |
---|
| | |
---|
| | |
---|
| | try { |
---|
| | Point2D srcMethodExecVxCellAbsPt = null; |
---|
| | Point2D dstMethodExecVxCellAbsPt = null; |
---|
| | final mxICell[] cloneDstMethodExecVxCell = new mxICell[1]; |
---|
| |
---|
| | } finally { |
---|
| | mxgraph.getModel().endUpdate(); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | |
---|
| | // Animate an edge to shrink. |
---|
| | MagnetRONAnimation edgeCellAnim = new TranslateAnimation(mxgraph, getGraphComponent()); |
---|
| | edgeCellAnim.setTotalCycleCount(getMagnetRONAnimationTotalCycleCount()); |
---|
| | edgeCellAnim.setDelay(getMagnetRONAnimationDelayMillis()); |
---|
| |
---|
| | } |
---|
| | } |
---|
| | }); |
---|
| | edgeCellAnim.play(); |
---|
| | |
---|
| | |
---|
| | if (!calledMethodExecution.isStatic()) { |
---|
| | objectToVertexMap.get(calledMethodExecution.getThisObjId()).getMethodExecutionVertices().remove(methodExecToVertexMap.get(calledMethodExecution)); |
---|
| | } else { |
---|
| | // TODO: Confirm why is this object id of the caller method used? |
---|
| |
---|
| | MethodExecution dstMethodExec = methodExecList.get(i + 1); |
---|
| | String methodSig = srcMethodExec.getSignature(); |
---|
| | |
---|
| | if (!edgeMap.containsKey(methodSig)) { |
---|
| | MagnetRONAnimation.waitAnimationEnd(); |
---|
| | |
---|
| | // Draw an edge from sourceVertexCell to destinationVertexCell. |
---|
| | mxICell srcMethodExecVxCell = (mxICell)methodExecToVertexMap.get(srcMethodExec).getCell(); |
---|
| | mxICell dstMethodExecVxCell = (mxICell)methodExecToVertexMap.get(dstMethodExec).getCell(); |
---|
| | Point2D srcMethodExecVxCellAbsPt = getAbsolutePointforCell(srcMethodExecVxCell); |
---|
| | Point2D dstMethodExecVxCellAbsPt = getAbsolutePointforCell(dstMethodExecVxCell); |
---|
| | |
---|
| | MagnetRONAnimation.waitAnimationEnd(); |
---|
| | scrollCellsToVisible(srcMethodExecVxCell.getParent(), dstMethodExecVxCell.getParent(), 2); |
---|
| | |
---|
| | try { |
---|
| | final mxICell[] cloneDstMethodExecVxCell = new mxICell[1]; |
---|
| |
---|
| | this.skipBackFrame = numberFrame; |
---|
| | } |
---|
| | |
---|
| | public void setAnimationSpeed(double animationSpeed) { |
---|
| | System.out.println(TAG + ": animationSpeed=" + animationSpeed); |
---|
| | this.animationSpeed = animationSpeed; |
---|
| | } |
---|
| | |
---|
| | protected int getCurrentFrame() { |
---|
| | return this.curFrame; |
---|
| | } |
---|
| | |
---|
| | protected int getPreviousFrame() { |
---|
| | return this.prevFrame; |
---|
| | } |
---|
| | |
---|
| | public int getSkipBackFrame() { |
---|
| | return this.skipBackFrame; |
---|
| |
---|
| | |