package org.ntlab.deltaViewer;
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;
import org.ntlab.deltaExtractor.IAliasCollector;
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;
import org.ntlab.trace.MethodInvocation;
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;
/**
* Make and display JGraph of extracted delta.
*
* @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
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;
public DeltaViewer() {
super();
}
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. */
public void initAnimation() {
// Fit graph size in visible JFrame.
mxGraphView view = mxgraphComponent.getGraph().getView();
int componentWidth = mxgraphComponent.getWidth() - 25;
double viewWidth = (double) view.getGraphBounds().getWidth();
// Object component = mxgraph.insertDeltaVertex(mxDefaultParent, "component", "component", "fillColor=white"); //creates a white vertex.
// ((mxICell)component).getGeometry().setX(mxgraphComponent.getWidth() - 30);
// ((mxICell)component).getGeometry().setY(10);
// Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, "view", "view", "fillColor=white"); //creates a white vertex.
// ((mxICell)vertex).getGeometry().setX(view.getGraphBounds().getWidth());
// ((mxICell)vertex).getGeometry().setY(10);
System.out.print("Scale " + componentWidth + ", " + viewWidth + ", " + coordinatorPoint.getX());
if (viewWidth < coordinatorPoint.getX()) {
viewWidth += coordinatorPoint.getX();
}
// scale = (double)componentWidth/viewWidth;
System.out.println(", " + scale);
// scale = 1.5;
view.setScale(scale);
deltaAnimation.setScale(scale);
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.
*
* @param alias Alias type and occurrence point etc.
*/
public void stepToAnimation(Alias alias) {
try {
stepToAnimation(aliasCollector.getAliasList().indexOf(alias));
} catch (IndexOutOfBoundsException e) {
stepToAnimation(-1);
}
}
/**
* Parent : Step to animation of specified numFrame.
*
* @param numFrame Current animation frame.
*/
public void stepToAnimation(int numFrame) {
if (aliasCollector.getAliasList().size() > numFrame) {
doAnimation(curFrame, numFrame);
} else if (aliasCollector.getAliasList().size() == numFrame){
System.out.println("\r\nLast Animation.");
doLastAnimation(numFrame);
} else {
System.out.println("ERROR : Not exist alias.");
}
}
/**
* 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<Alias> 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.
*/
private void doLastAnimation(int numFrame) {
outputLog();
curFrame = numFrame;
Alias alias = aliasCollector.getAliasList().get(numFrame - 1);
// Make ObjectEdge and reset position of vertexObject, remove vertexMethodExecution.
// for(Statement statement: alias.getMethodExecution().getStatements())
{
Statement statement = eStructure.getRelatedTracePoint().getStatement();
MethodExecution methodExec = alias.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(methodExec)) {
if (methodExecToVertexMap.get(methodExec).getLocals().contains(targetObjectVertex)) {
methodExecToVertexMap.get(methodExec).getLocals().remove(targetObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + targetObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(methodExec).getArguments().contains(targetObjectVertex)) {
methodExecToVertexMap.get(methodExec).getArguments().remove(targetObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + targetObjectVertex.getLabel());
}
}
removeCalledMethodExecutionVertex(objectToVertexMap.get(sourceObjectId), methodExec.getCallerMethodExecution(), methodExec);
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のときだけラベルを付ける(確実に分かっているものとき)getSignature->contains("List.get(") || "Map.get(") <ホワイトリスト>
// 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(methodExec)) {
if (methodExecToVertexMap.get(methodExec).getLocals().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(methodExec).getLocals().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(methodExec).getArguments().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(methodExec).getArguments().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel());
}
}
List<MethodExecution> methodExecList = new ArrayList<>(methodExecToVertexMap.keySet());
System.out.println(methodExecList.size());
if (methodExecList.size() > 1) {
removeCalledMethodExecutionVertex(null, methodExec.getCallerMethodExecution(), methodExec);
} else {
removeCalledMethodExecutionVertex(null, null, methodExec);
}
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(methodExec)) {
if (methodExecToVertexMap.get(methodExec).getLocals().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(methodExec).getLocals().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(methodExec).getArguments().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(methodExec).getArguments().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(methodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel());
}
}
removeCalledMethodExecutionVertex(objectToVertexMap.get(srcObjId), methodExec, calledMethodExec);
updateObjectVertices();
}
}
}
// MethodExecution tempMethodExec = alias.getMethodExecution();
// //ArrayやListのときだけラベルを付ける(確実に分かっているものとき)getSignature->contains("List.get(") || "Map.get(") <ホワイトリスト>
// 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 {
List<MethodExecution> methodExecList = new ArrayList<>(methodExecToVertexMap.keySet());
Collections.reverse(methodExecList);
System.out.println(methodExecList.size());
for(int i = 0; i < methodExecList.size(); i++) {
String objectId = methodExecList.get(i).getThisObjId();
ObjectVertex sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex
MethodExecution methodExec = methodExecList.get(i);
if (i != methodExecList.size()-1) {
for(Statement statement: methodExec.getStatements()) {
if(statement instanceof MethodInvocation) {
MethodExecution calledMethodExec = ((MethodInvocation) statement).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 + ", " + methodExec.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, methodExec.getCallerMethodExecution(), methodExec);
updateObjectVertices();
// removeVertexMethodExecution(sourceVertexObject, methodExec);
// update();
break;
}
}
}
} else {
outputLog();
// Change!
List<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(methodExec).getArguments());
List<ObjectVertex> locals = new ArrayList<>(methodExecToVertexMap.get(methodExec).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(methodExec).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(methodExec).getLocals().remove(vo);
}
}
updateObjectVertices();
}
}
} finally {
mxgraph.getModel().endUpdate();
}
update();
}
/** Create ObjectVertices. */
private void createObjectVertices(ExtractedStructure eStructure) {
Delta delta = eStructure.getDelta();
double time = 150;
double padding = 200;
coordinatorPoint.setX(coordinatorPoint.getX() + (time * delta.getDstSide().size()) + padding);
// 左上(0, 0)
double xCor = coordinatorPoint.getX();
double yCor = coordinatorPoint.getY();
//Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
// Draw vertex object.
// srcSide
int srcSideSize = delta.getSrcSide().size();
MethodExecution coordinator = eStructure.getCoordinator();
String coordinatorObjId = coordinator.getThisObjId();
String coordinatorClassName = coordinator.getThisClassName();
for (int i = srcSideSize - 1; i >= 0; i--) {
Reference ref = delta.getSrcSide().get(i);
if (i == srcSideSize - 1 && !coordinatorObjId.equals(ref.getSrcObjectId()) && !coordinatorClassName.equals(ref.getSrcClassName())) {
System.out.println("coordinator: " + coordinatorClassName + ", " + coordinatorObjId);
coordinatorPoint.setX(coordinatorPoint.getX() + time * 2);
xCor += time * 2;
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))));
srcSideSize++;
}
System.out.println("srcSide: " + ref.getSrcClassName() + ", " + ref.isCreation() + ", " + ref.getSrcObjectId());
if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
if (!objectToVertexMap.containsKey(ref.getSrcObjectId())) {
String srcClassName = ref.getSrcClassName();
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))));
}
if (!objectToVertexMap.containsKey(ref.getDstObjectId())) {
System.out.println(ref.getDstClassName() + ", " + ref.isCreation());
String dstClassName = ref.getDstClassName();
if (dstClassName.contains("[L")) {
dstClassName = formatArrayName(dstClassName);
}
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i))));
}
} else {
String srcClassName = ref.getSrcClassName();
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor + (time * ((srcSideSize - 1) - i)), yCor + (time * ((srcSideSize - 1) - i))));
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), null, xCor + (time * (srcSideSize - i)), yCor + (time * (srcSideSize - i))));
}
}
// dstSide
int dstSideSize = delta.getDstSide().size();
int cnt = 0;
for (int i = dstSideSize - 1; i >= 0; i--) {
Reference ref = delta.getDstSide().get(i);
if (i == dstSideSize - 1 && srcSideSize == 0 && !coordinatorObjId.equals(ref.getSrcObjectId()) && !coordinatorClassName.equals(ref.getSrcClassName())) {
System.out.println("coordinator: " + coordinatorClassName + ", " + coordinatorObjId);
coordinatorPoint.setX(coordinatorPoint.getX() + time * 2);
xCor += time * 2;
System.out.println(coordinatorPoint.getX() + ", " + xCor);
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, coordinatorObjId, coordinatorClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))));
dstSideSize++;
}
System.out.println("dstSide: " + ref.getSrcClassName() + ", " + ref.getDstClassName() + ", " + ref.isCreation());
if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
if (!objectToVertexMap.containsKey(ref.getSrcObjectId())) {
String srcClassName = ref.getSrcClassName();
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getSrcObjectId(), srcClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))));
cnt++;
}
if (!objectToVertexMap.containsKey(ref.getDstObjectId())) {
String dstClassName = ref.getDstClassName();
if (dstClassName.contains("[L")) {
dstClassName = formatArrayName(dstClassName);
}
Object vertex = mxgraph.insertDeltaVertex(mxDefaultParent, ref.getDstObjectId(), dstClassName, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt)), VERTEX_OBJECT_SIZE.getWidth(), VERTEX_OBJECT_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))));
}
} else {
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), null, xCor - (time * (dstSideSize - i + cnt)), yCor + (time * (dstSideSize - i + cnt))));
}
}
} finally {
mxgraph.getModel().endUpdate();
}
}
/**
* 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 { // 仕様上のバグ, ループが発生
outputLog();
// try {
// ObjectVertex(sourceCell)のクローン生成
// 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) {
// // moveInitialVertexObject((MethodInvocation) statement);
// MethodExecution calledMethodExec = ((MethodInvocation)statement).getCalledMethodExecution();
// String calledObjectId = calledMethodExec.getThisObjId();
// mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell();
// Point absolutePointCalledCell = getAbsolutePointforCell(calledCell);
// // System.out.println(objectId + ", " + methodExec.getSignature());
// // objectToVertexMap.get(calledObjectId).resetCellPosition();
// if (methodExecToVertexMap.get(methodExecution).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExecution).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();
// break;
// }
// }
// }
// }
/** 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<ObjectVertex> 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();
// }
// }
/**
* Create MethodExecutionVertex.
*
* @param alias
*/
private 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()) && eStructure.getCoordinator() == callerMethodExec) {
createMethodExecutionVertex(callerMethodExec.getThisObjId(), callerMethodExec.getSignature(), callerMethodExec);
}
createMethodExecutionVertex(objId, methodExecSignature, methodExec);
} else if (alias.getObjectId().matches("0") && !methodExecToVertexMap.containsKey(methodExec)) {
createMethodExecutionVertex(objId, methodExecSignature, methodExec);
}
}
/**
* 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<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments());
List<ObjectVertex> 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<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(calledMethodExec).getArguments());
List<ObjectVertex> 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) {
// 右下から左上へエッジを引く
edge.setStyle("exitX=1;exitY=1;exitPerimeter=1;entryX=0;entryY=0;entryPerimeter=1;");
} else {
// 左下から右上へエッジを引く
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
*/
private void createEdgeToObject(List<Alias> aliasList) {
for (int i = 0; i < aliasList.size()-1; i++) {
Alias curAlias = aliasList.get(i);
Alias nextAlias = aliasList.get(i+1);
String srcClassName = null;
String fieldName = null;
if (curAlias.getAliasType().equals(AliasType.THIS) /*&& nextAlias.getAliasType().equals(AliasType.FIELD)*/) {
if (nextAlias.getAliasType().equals(AliasType.RETURN_VALUE)) {
MethodExecution nextMethodExec = nextAlias.getMethodExecution();
//ArrayやListのときだけラベルを付ける(確実に分かっているものとき)getSignature->contains("List.get(") || "Map.get(") <ホワイトリスト>
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 && curAlias.getObjectId().equals(((FieldAccess)statement).getContainerObjId())) {
String fieldNames[] = formatFieldName(((FieldAccess)statement).getFieldName());
srcClassName = fieldNames[0];
fieldName = fieldNames[1];
}
}
System.out.println("THIS " + srcClassName + "(" + curAlias.getObjectId() + ") -> " + "(" + nextAlias.getObjectId() + "), "+ fieldName);
}
if(curAlias.getAliasType().equals(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 + "(" + curAlias.getObjectId() + ") -> " + "(" + nextAlias.getObjectId() + "), " + fieldName);
}
}
if (srcClassName != null && fieldName != null && srcClassName != null && !edgeMap.containsKey(srcClassName + "." + fieldName)) {
// 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(curAlias.getObjectId()).getCell();
Object dstCell = objectToVertexMap.get(nextAlias.getObjectId()).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();
}
}
}
}
/** Make EdgeMethodExecution. */
private void createEdgeToMethodExecution() {
List<MethodExecution> 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);
// }
}
}
}
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;
}
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;
}
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 String formatArrayIndex(int index) {
StringBuffer sb = new StringBuffer();
sb.append("[");
sb.append(index);
sb.append("]");
return sb.toString();
}
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<String, ObjectVertex> 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());
}
}
}
}