package org.ntlab.deltaViewer;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.ntlab.animations.MagnetRONAnimation;
import org.ntlab.animations.TranslateAnimation;
import org.ntlab.deltaExtractor.Alias;
import org.ntlab.deltaExtractor.IAliasCollector;
import org.ntlab.deltaExtractor.Alias.AliasType;
import org.ntlab.deltaViewer.Edge.TypeName;
import org.ntlab.trace.ArrayAccess;
import org.ntlab.trace.FieldAccess;
import org.ntlab.trace.FieldUpdate;
import org.ntlab.trace.MethodExecution;
import org.ntlab.trace.MethodInvocation;
import org.ntlab.trace.Reference;
import org.ntlab.trace.Statement;
import org.ntlab.trace.TracePoint;
import com.mxgraph.model.mxICell;
import com.mxgraph.view.mxGraphView;
public class CollaborationViewer extends MagnetRONViewer {
private static final long serialVersionUID = 9123813231037494846L;
// Test code (will be deleted)
private static final String TAG = CollaborationViewer.class.getSimpleName();
private IObjectCallGraph objectCallGraph;
private double scale = 1;
public CollaborationViewer() {
super();
}
/**
* Set objectCallGraph and aliasCollector, create vertex object and edge object.
* @param objectCallGraph
* @param aliasCollector
*/
public void init(IObjectCallGraph objectCallGraph, IAliasCollector aliasCollector, IObjectLayout layout) {
this.objectCallGraph = objectCallGraph;
this.aliasCollector = aliasCollector;
createObjectVertices(this.objectCallGraph);
layout.execute(objectCallGraph, aliasCollector, objectToVertexMap);
createEdgeToObject(this.objectCallGraph, this.aliasCollector);
}
/**
* Initialize animation. (再生ボタンを押すとき)
*/
public void initAnimation() {
// reflectCoordinates(mxgraph); // objectVertexにmxGraphの座標を反映させる(ユーザが指定した座標位置を反映)
// 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);
// scale = (double)componentWidth/viewWidth;
System.out.println(", " + scale);
// scale = 1.5;
view.setScale(scale);
// deltaAnimation.setScale(scale);
update();
}
/**
* 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) {
// TODO: Implement doLastAnimation to support plural Delta.
// TODO: curFrame debug.
System.out.println(TAG + ": Frame=" + curFrame + "->" + numFrame);
// if (numFrame - curFrame == 1) {
List<TracePoint> relatedPoints = objectCallGraph.getRelatedPoints();
List<Alias> aliasList = aliasCollector.getAliasList();
Alias curFrameAlias = (0 < numFrame && numFrame <= aliasList.size()) ? aliasList.get(numFrame- 1) : null;
Alias numFrameAlias = (0 <= numFrame && numFrame < aliasList.size()) ? aliasList.get(numFrame) : null;
if (numFrameAlias != null) {
if (curFrameAlias != null) {
for (TracePoint rp: relatedPoints) {
if (curFrameAlias.getTimeStamp() < rp.getStatement().getTimeStamp() && rp.getStatement().getTimeStamp() < numFrameAlias.getTimeStamp()) {
System.out.println("\r\n" + TAG + ": Last Animation.");
doLastAnimation(numFrame, rp);
return;
}
}
}
doAnimation(curFrame, numFrame);
} else if (curFrameAlias != null && numFrameAlias == null) {
System.out.println("\r\n" + TAG + ": Last Animation.");
doLastAnimation(numFrame, relatedPoints.get(relatedPoints.size() - 1));
} else {
System.out.println(TAG + ": ERROR Not exist alias.");
}
// } else {
// TODO: Considering fast-forwarding animations.
// }
}
private void doLastAnimation(int numFrame, TracePoint relatedPoint) {
// TODO: Implement doLastAnimation to support plural Delta.
curFrame = numFrame;
List<Alias> aliasList = aliasCollector.getAliasList();
Alias prevAlias = aliasList.get(numFrame - 1);
Alias nextAlias = (numFrame < aliasList.size()) ? aliasList.get(numFrame) : null;
// Make ObjectEdge and reset position of vertexObject, remove vertexMethodExecution.
Statement statement = relatedPoint.getStatement();
MethodExecution prevMethodExec = prevAlias.getMethodExecution();
boolean fThisAnotherParameter = false;
if (relatedPoint.isMethodEntry()) {
if (prevAlias.getAliasType() == Alias.AliasType.FORMAL_PARAMETER) {
// this to another (parameter)
MethodExecution calledMethodExec = relatedPoint.getMethodExecution();
String srcClassName = calledMethodExec.getThisClassName();
String srcObjId = calledMethodExec.getThisObjId();
String tgtObjId = prevAlias.getObjectId();
ObjectVertex tgtObjectVertex = objectToVertexMap.get(tgtObjId);
createObjectRefrence(srcClassName, srcObjId, tgtObjId);
if (methodExecToVertexMap.containsKey(prevMethodExec)) {
if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getLocals().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getArguments().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel());
}
}
if (nextAlias == null || (nextAlias != null && !calledMethodExec.getSignature().equals(nextAlias.getMethodSignature()))) {
removeCalledMethodExecutionVertex(objectToVertexMap.get(srcObjId), prevMethodExec, calledMethodExec);
updateObjectVertices();
}
fThisAnotherParameter = true;
}
}
if (!fThisAnotherParameter) {
if (statement instanceof FieldUpdate) {
// Format fieldName.
FieldUpdate fieldUpdateStatement = (FieldUpdate) statement;
String fieldName;
if (fieldUpdateStatement.getFieldName() != null) {
String fieldNames[] = formatFieldName(fieldUpdateStatement.getFieldName());
fieldName = fieldNames[fieldNames.length-1];
} else {
fieldName = "";
}
String sourceObjectId = fieldUpdateStatement.getContainerObjId();
createObjectRefrence(fieldUpdateStatement, fieldName);
// Change!
String targetObjectId = fieldUpdateStatement.getValueObjId();
ObjectVertex targetObjectVertex = objectToVertexMap.get(targetObjectId);
if (methodExecToVertexMap.containsKey(prevMethodExec)) {
if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(targetObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getLocals().remove(targetObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + targetObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(targetObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getArguments().remove(targetObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + targetObjectVertex.getLabel());
}
}
if (nextAlias == null || (nextAlias != null && !prevMethodExec.getSignature().equals(nextAlias.getMethodSignature()))) {
removeCalledMethodExecutionVertex(objectToVertexMap.get(sourceObjectId), prevMethodExec.getCallerMethodExecution(), prevMethodExec);
updateObjectVertices();
}
}
if(statement instanceof MethodInvocation) {
MethodInvocation methodInvStatement = (MethodInvocation) statement;
MethodExecution calledMethodExec = methodInvStatement.getCalledMethodExecution();
String methodSignature = calledMethodExec.getSignature();
String srcClassName = null;
String srcObjId = null;
String tgtObjId = null;
//ArrayやListのときだけラベルを付ける(確実に分かっているものとき)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);
if (!methodExecToVertexMap.containsKey(calledMethodExec)) {
createMethodExecutionVertex(calledMethodExec.getThisObjId(), methodInvStatement.getCallerSideMethodName(), calledMethodExec);
update();
moveArgumentObjectVertex(calledMethodExec, tgtObjectVertex, methodExecToVertexMap.get(calledMethodExec));
update();
createObjectRefrence(srcClassName, srcObjId, tgtObjId);
removeCalledMethodExecutionVertex(null, prevMethodExec, calledMethodExec);
} else {
createObjectRefrence(srcClassName, srcObjId, tgtObjId);
}
if (methodExecToVertexMap.containsKey(prevMethodExec)) {
if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getLocals().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getArguments().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel());
}
}
List<MethodExecution> methodExecList = new ArrayList<>(methodExecToVertexMap.keySet());
System.out.println(methodExecList.size());
if (nextAlias == null || (nextAlias != null && !prevMethodExec.getSignature().equals(nextAlias.getMethodSignature()))) {
if (methodExecList.size() > 1) {
removeCalledMethodExecutionVertex(null, prevMethodExec.getCallerMethodExecution(), prevMethodExec);
} else {
removeCalledMethodExecutionVertex(null, null, prevMethodExec);
}
}
updateObjectVertices();
} else {
// this to another
srcClassName = methodInvStatement.getThisClassName();
srcObjId = methodInvStatement.getThisObjId();
tgtObjId = calledMethodExec.getReturnValue().getId();
ObjectVertex tgtObjectVertex = objectToVertexMap.get(tgtObjId);
createObjectRefrence(srcClassName, srcObjId, tgtObjId);
if (methodExecToVertexMap.containsKey(prevMethodExec)) {
if (methodExecToVertexMap.get(prevMethodExec).getLocals().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getLocals().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeLocal: " + tgtObjectVertex.getLabel());
} else if (methodExecToVertexMap.get(prevMethodExec).getArguments().contains(tgtObjectVertex)) {
methodExecToVertexMap.get(prevMethodExec).getArguments().remove(tgtObjectVertex);
System.out.println(methodExecToVertexMap.get(prevMethodExec).getLabel() + " :removeArgument: " + tgtObjectVertex.getLabel());
}
}
if (nextAlias == null || (nextAlias != null && !calledMethodExec.getSignature().equals(nextAlias.getMethodSignature()))) {
removeCalledMethodExecutionVertex(objectToVertexMap.get(srcObjId), prevMethodExec, 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();
// }
List<MethodExecution> meList = new ArrayList<>(methodExecToVertexMap.keySet());
Collections.reverse(meList);
System.out.println(meList.size());
for(int i = 0; i < meList.size(); i++) {
String objectId = meList.get(i).getThisObjId();
ObjectVertex sourceVertexObject = objectToVertexMap.get(objectId); // sourceVertex
MethodExecution me = meList.get(i);
if (nextAlias != null && me.getSignature().equals(nextAlias.getMethodSignature())) break;
if (i != meList.size()-1) {
for(Statement st: me.getStatements()) {
if(st instanceof MethodInvocation) {
MethodExecution calledMethodExec = ((MethodInvocation) st).getCalledMethodExecution();
String calledObjectId = calledMethodExec.getThisObjId();
System.out.println(calledObjectId);
if(objectToVertexMap.containsKey(calledObjectId)) {
mxICell calledCell = (mxICell)objectToVertexMap.get(calledObjectId).getCell();
Point2D absolutePointCalledCell = getAbsolutePointforCell(calledCell);
System.out.println(objectId + ", " + me.getSignature());
// objectToVertexMap.get(calledObjectId).resetCellPosition();
// if (methodExecToVertexMap.get(methodExec).getArguments().contains(objectToVertexMap.get(calledObjectId)) || methodExecToVertexMap.get(methodExec).getLocals().contains(objectToVertexMap.get(calledObjectId))) {
// calledCell.getParent().remove(calledCell);
// calledCell.setParent(mxDefaultParent);
// calledCell.getGeometry().setX(absolutePointCalledCell.getX());
// calledCell.getGeometry().setY(absolutePointCalledCell.getY());
// deltaAnimation.setVertexAnimation(calledCell, new mxPoint(objectToVertexMap.get(calledObjectId).getInitialX(), objectToVertexMap.get(calledObjectId).getInitialY()));
// deltaAnimation.startVertexAnimation();
// }
removeCalledMethodExecutionVertex(sourceVertexObject, me.getCallerMethodExecution(), me);
updateObjectVertices();
// removeVertexMethodExecution(sourceVertexObject, methodExec);
// update();
break;
}
}
}
} else {
outputLog();
// Change!
List<ObjectVertex> arguments = new ArrayList<>(methodExecToVertexMap.get(me).getArguments());
List<ObjectVertex> locals = new ArrayList<>(methodExecToVertexMap.get(me).getLocals());
if (arguments.size() != 0) {
for (ObjectVertex vo: arguments) {
mxICell cell = (mxICell)vo.getCell();
Point2D absolutePointCell = getAbsolutePointforCell(cell);
// 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 {
// cell.getParent().remove(cell);
// cell.setParent(mxDefaultParent);
if (!cell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
cell.getParent().remove(cell);
cell.setParent(getMxDefaultParent());
}
cell.getGeometry().setX(absolutePointCell.getX());
cell.getGeometry().setY(absolutePointCell.getY());
} finally {
mxgraph.getModel().endUpdate();
}
}
// deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
// deltaAnimation.startVertexAnimation();
// deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS);
MagnetRONAnimation vertexAnim = new TranslateAnimation(mxgraph, getGraphComponent());
vertexAnim.setTotalCycleCount(10);
vertexAnim.setDelay(100);
vertexAnim.init(cell, vo.getInitialX(), vo.getInitialY(), threadPoolExecutor);
// vertexAnim.play();
// sleepMainThread(DEFAULT_THREAD_SLEEP_MILLIS);
vertexAnim.syncPlay();
methodExecToVertexMap.get(me).getArguments().remove(vo);
}
}else if (locals.size() != 0) {
for (ObjectVertex vo: locals) {
mxICell cell = (mxICell)vo.getCell();
Point2D absolutePointCell = getAbsolutePointforCell(cell);
// 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 {
// cell.getParent().remove(cell);
// cell.setParent(mxDefaultParent);
if (!cell.getParent().equals(getMxDefaultParent())) {
// If parent of ObjectVertex cell isn't mxDefaltParent, reset parent.
cell.getParent().remove(cell);
cell.setParent(getMxDefaultParent());
}
cell.getGeometry().setX(absolutePointCell.getX());
cell.getGeometry().setY(absolutePointCell.getY());
} finally {
mxgraph.getModel().endUpdate();
}
}
// deltaAnimation.setVertexAnimation(cell, new mxPoint(vo.getInitialX(), vo.getInitialY()));
// deltaAnimation.startVertexAnimation();
// deltaAnimation.sleepThread(DEFAULT_THREAD_SLEEP_MILLIS);
MagnetRONAnimation vertexAnim = new TranslateAnimation(mxgraph, getGraphComponent());
vertexAnim.setTotalCycleCount(10);
vertexAnim.setDelay(100);
vertexAnim.init(cell, vo.getInitialX(), vo.getInitialY(), threadPoolExecutor);
// vertexAnim.play();
// sleepMainThread(DEFAULT_THREAD_SLEEP_MILLIS);
vertexAnim.syncPlay();
methodExecToVertexMap.get(me).getLocals().remove(vo);
}
}
updateObjectVertices();
}
}
update();
}
/**
* Create vertices(mxGraph) and objectVertices in objectToVertexMap. Vertices(mxGraph) coordinate are appropriate.
* @param objectCallGraph
*/
private void createObjectVertices(IObjectCallGraph objectCallGraph) {
//Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
// Create vertices(mxGraph) and objectVertices.
List<Reference> refList = objectCallGraph.getReferences();
int ocgSize = refList.size();
double vertexObjWidth = DEFAULT_OBJECT_VERTEX_SIZE.getWidth();
double vertexObjHeight = DEFAULT_OBJECT_VERTEX_SIZE.getHeight();
{
MethodExecution coordinator = objectCallGraph.getStartPoints().get(0);
String coordinatorObjId = coordinator.getThisObjId();
String coordinatorClassName = coordinator.getThisClassName();
Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), coordinatorObjId, coordinatorClassName, 0, 0, DEFAULT_OBJECT_VERTEX_SIZE.getWidth(), DEFAULT_OBJECT_VERTEX_SIZE.getHeight(), "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(coordinatorObjId, new ObjectVertex(coordinatorClassName, vertex, 0, 0));
}
for (int i = 0; i < ocgSize; i++) {
Reference ref = refList.get(i);
if (!ref.isCreation() && !ref.getSrcObjectId().equals(ref.getDstObjectId())) {
// srcSide
if (!objectToVertexMap.containsKey(ref.getSrcObjectId())) {
System.out.println("srcSide: " + ref.getSrcClassName() + ", " + ref.getSrcObjectId() + ": " + ref.isCreation());
String srcClassName = ref.getSrcClassName();
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0));
}
// dstSide
if (!objectToVertexMap.containsKey(ref.getDstObjectId())) {
System.out.println("dstSide: " + ref.getDstClassName() + ", " + ref.getDstObjectId());
String dstClassName = ref.getDstClassName();
if (dstClassName.contains("[L")) {
dstClassName = formatArrayName(dstClassName);
}
Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getDstObjectId(), dstClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), vertex, 0, 0));
}
} else {
if (!objectToVertexMap.containsKey(ref.getSrcObjectId())) {
String srcClassName = ref.getSrcClassName();
if (srcClassName.contains("[L")) {
srcClassName = formatArrayName(srcClassName);
}
Object vertex = mxgraph.insertDeltaVertex(getMxDefaultParent(), ref.getSrcObjectId(), srcClassName, 0, 0, vertexObjWidth, vertexObjHeight, "fillColor=white"); //creates a white vertex.
objectToVertexMap.put(ref.getSrcObjectId(), new ObjectVertex(ref.getSrcClassName(), vertex, 0, 0));
}
if (!objectToVertexMap.containsKey(ref.getDstObjectId())) {
objectToVertexMap.put(ref.getDstObjectId(), new ObjectVertex(ref.getDstClassName(), null, 0, 0));
} else {
mxgraph.removeCells(new Object[] {objectToVertexMap.get(ref.getDstObjectId()).getCell()});
objectToVertexMap.get(ref.getDstObjectId()).setCell(null);
}
}
}
} finally {
mxgraph.getModel().endUpdate();
}
}
/**
* Create MethodExecutionVertex. Be careful to refer objectCallGraph.getStartPoints() when curFrame is 0.
*
* @param alias
*/
@Override
public void createMethodExecutionVertex(Alias alias) {
String objId = alias.getObjectId();
MethodExecution methodExec = alias.getMethodExecution();
String methodExecSignature = methodExec.getSignature();
if (curFrame == 0) {
MethodExecution callerMethodExec = methodExec.getCallerMethodExecution();
if (callerMethodExec != null && methodExecSignature != callerMethodExec.getSignature() && objectToVertexMap.containsKey(callerMethodExec.getThisObjId()) && objectCallGraph.getStartPoints().get(0) == callerMethodExec) {
createMethodExecutionVertex(callerMethodExec.getThisObjId(), callerMethodExec.getSignature(), callerMethodExec);
}
createMethodExecutionVertex(objId, methodExecSignature, methodExec);
} else if (alias.getObjectId().matches("0") && !methodExecToVertexMap.containsKey(methodExec)) {
createMethodExecutionVertex(objId, methodExecSignature, methodExec);
}
}
/**
*
* @param ocg
* @param ac
*/
private void createEdgeToObject(IObjectCallGraph ocg, IAliasCollector ac) {
List<TracePoint> relatedPoints = ocg.getRelatedPoints();
int rpIndex = 0; // relatedPoints index
List<Alias> aliasList = ac.getAliasList();
for (int i = 0; i < aliasList.size()-1; i++) {
Alias curAlias = aliasList.get(i);
Alias nextAlias = aliasList.get(i+1);
String curAliasObjId = curAlias.getObjectId(); // srcObjId
String nextAliasObjId = nextAlias.getObjectId(); // dstObjId
String srcClassName = null;
String fieldName = null;
// Search for objectReference srcClassName, fieldName between curAlias and nexAlias.
if (curAlias.getAliasType() == AliasType.THIS) {
if (nextAlias.getAliasType() == AliasType.RETURN_VALUE) {
MethodExecution nextMethodExec = nextAlias.getMethodExecution();
//ArrayやListのときだけラベルを付ける(確実に分かっているものとき)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 && curAliasObjId.equals(((FieldAccess)statement).getContainerObjId())) {
if (((FieldAccess)statement).getFieldName() != null) {
String fieldNames[] = formatFieldName(((FieldAccess)statement).getFieldName());
srcClassName = fieldNames[0];
fieldName = fieldNames[1];
} else {
srcClassName = ((FieldAccess)statement).getContainerClassName();
fieldName = "";
}
}
}
System.out.println("THIS " + srcClassName + "(" + curAliasObjId + ") -> " + "(" + nextAliasObjId + "), "+ fieldName);
}
if(curAlias.getAliasType() == AliasType.ARRAY) {
Statement statement= nextAlias.getOccurrencePoint().getStatement();
if(statement instanceof ArrayAccess) {
srcClassName = ((ArrayAccess)statement).getArrayClassName();
int index = ((ArrayAccess)statement).getIndex();
fieldName = formatArrayIndex(index);
System.out.println("ARRAY " + srcClassName + "(" + curAliasObjId + ") -> " + "(" + nextAliasObjId + "), " + fieldName);
}
}
if (srcClassName != null && fieldName != null && !edgeMap.containsKey(srcClassName + "." + fieldName)) {
// Judge AliasList contains relatedPoint. (If contains not to create edge.)
if (rpIndex < relatedPoints.size() - 1) {
TracePoint rp = relatedPoints.get(rpIndex);
Map.Entry<Reference, String> rpInf = getRelatedInformation(rp, ac);
if (srcClassName.equals(rpInf.getKey().getSrcClassName()) && fieldName.equals(rpInf.getValue()) && curAliasObjId.equals(rpInf.getKey().getSrcObjectId()) && nextAliasObjId.equals(rpInf.getKey().getDstObjectId())) {
rpIndex++;
continue;
}
}
// Add a vertex to the graph in a transactional fashion. The vertex is actually a 'cell' in jgraphx terminology.
mxgraph.getModel().beginUpdate();
try {
Object srcCell = objectToVertexMap.get(curAliasObjId).getCell();
Object dstCell = objectToVertexMap.get(nextAliasObjId).getCell();
if (srcCell != null && dstCell != null) { // isCreation()
System.out.println("makeEdgeObject: " + fieldName + ", " + srcClassName + " (" + srcCell.hashCode() + "), " + " (" + dstCell.hashCode() + ")"/* + ", " + dstClassName*/);
// BUG:NullPointerException
Object edge = mxgraph.insertDeltaEdge(getMxDefaultParent(), fieldName, fieldName, srcCell, dstCell);
Point2D absPtSrcCell = getAbsolutePointforCell((mxICell)srcCell);
Point2D absPtDstCell = getAbsolutePointforCell((mxICell)dstCell);
setEdgePoint((mxICell)edge, absPtSrcCell, absPtDstCell);
edgeMap.put(srcClassName + "." + fieldName, new Edge(fieldName, TypeName.Reference, edge));
}
} finally {
mxgraph.getModel().endUpdate();
}
}
}
}
}