diff --git a/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java b/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java index 9f22d79..c1be68f 100644 --- a/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java +++ b/src/org/ntlab/deltaViewer/CollaborationAliasCollector.java @@ -7,6 +7,9 @@ import org.ntlab.deltaExtractor.Alias; import org.ntlab.deltaExtractor.IAliasCollector; +import org.ntlab.featureExtractor.Extract; +import org.ntlab.trace.MethodExecution; +import org.ntlab.trace.TracePoint; /** * CollaborationAliasCollector is IAliasCollector implementation class to merge aliasList in time stamp order. @@ -37,15 +40,32 @@ /** * Merge other into aliasList(this) in time stamp order. * @param other�@IAliasCollector to be merged into the aliasList. + * @param extract */ - public void merge(IAliasCollector other) { + public void merge(IAliasCollector other, Extract extract) { List otherAliasList = other.getAliasList(); otherAliasList = sortAliasListByTimeStamp(otherAliasList); - int otherIdx = 0; // Index of otherAliasList - int thisIdx = 0; // Index of thisAliasList + int otherIdx = 0; // Index in otherAliasList + int thisIdx = 0; // Index in thisAliasList + int thisOrgIdx = 0; // Index in the original thisAliasList while(otherIdx < otherAliasList.size()) { Alias otherAlias = otherAliasList.get(otherIdx); if (thisIdx >= aliasList.size()) { + if (extract != null && extract.isToConnect() && otherIdx == 0) { + Alias thisPrevAlias = aliasList.get(aliasList.size() - 1); + if (!otherAlias.getMethodExecution().isStatic() && otherAlias.getMethodExecution().getCallerMethodExecution() != thisPrevAlias.getMethodExecution()) { + // Add a dummy alias to connect disjunct call hierarchies. (thisPrevAlias -> otherAlias) + MethodExecution caller = thisPrevAlias.getMethodExecution(); +// MethodExecution callee = new DummyMethodExecution(otherAlias.getMethodExecution()); // Currently does not work because this dummy and the original one will be mixed. + MethodExecution callee = otherAlias.getMethodExecution(); + callee.setCaller(caller, caller.getStatements().indexOf(thisPrevAlias.getOccurrencePoint().getStatement())); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, thisPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); + thisIdx++; + } + } aliasList.add(otherAlias); otherIdx++; thisIdx++; continue; @@ -53,16 +73,46 @@ Alias thisAlias = aliasList.get(thisIdx); if (otherAlias.equals(thisAlias)) { - otherIdx++; thisIdx++; + otherIdx++; thisIdx++; thisOrgIdx++; } else { long otherAliasTs = otherAlias.getTimeStamp(); long thisAliasTs = thisAlias.getTimeStamp(); if (otherAliasTs < thisAliasTs) { + if (extract != null && extract.isToConnect() && otherIdx == 0 && thisIdx > 0) { + Alias thisPrevAlias = aliasList.get(thisIdx - 1); + if (!otherAlias.getMethodExecution().isStatic() && otherAlias.getMethodExecution().getCallerMethodExecution() != thisPrevAlias.getMethodExecution()) { + // Add a dummy alias to connect disjunct call hierarchies. (thisPrevAlias -> otherAlias) + MethodExecution caller = thisPrevAlias.getMethodExecution(); +// MethodExecution callee = new DummyMethodExecution(otherAlias.getMethodExecution()); // Currently does not work because this dummy and the original one will be mixed. + MethodExecution callee = otherAlias.getMethodExecution(); + callee.setCaller(caller, caller.getStatements().indexOf(thisPrevAlias.getOccurrencePoint().getStatement())); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, thisPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); + thisIdx++; + } + } aliasList.add(thisIdx, otherAlias); otherIdx++; thisIdx++; } else if (otherAliasTs > thisAliasTs) { - thisIdx++; + if (extract != null && extract.isToConnect() && thisOrgIdx == 0 && otherIdx > 0) { + Alias otherPrevAlias = otherAliasList.get(otherIdx - 1); + if (!thisAlias.getMethodExecution().isStatic() && thisAlias.getMethodExecution().getCallerMethodExecution() != otherPrevAlias.getMethodExecution()) { + // Add a dummy alias to connect disjunct call hierarchies. (otherPrevAlias -> thisAlias) + MethodExecution caller = otherPrevAlias.getMethodExecution(); +// MethodExecution callee = new DummyMethodExecution(thisAlias.getMethodExecution()); // Currently does not work because this dummy and the original one will be mixed. + MethodExecution callee = thisAlias.getMethodExecution(); + callee.setCaller(caller, caller.getStatements().indexOf(otherPrevAlias.getOccurrencePoint().getStatement())); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, otherPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); + thisIdx++; + } + } + thisIdx++; thisOrgIdx++; } else { if (aliasList.contains(otherAlias)) { otherIdx++; @@ -74,6 +124,21 @@ } } } + if (extract != null && extract.isToConnect() && thisOrgIdx == 0 && otherIdx > 0 && thisIdx < aliasList.size()) { + Alias thisAlias = aliasList.get(thisIdx); + Alias otherPrevAlias = otherAliasList.get(otherIdx - 1); + if (!thisAlias.getMethodExecution().isStatic() && thisAlias.getMethodExecution().getCallerMethodExecution() != otherPrevAlias.getMethodExecution()) { + // Add a dummy alias to connect disjunct call hierarchies. (otherPrevAlias -> thisAlias) + MethodExecution caller = otherPrevAlias.getMethodExecution(); +// MethodExecution callee = new DummyMethodExecution(thisAlias.getMethodExecution()); // Currently does not work because this dummy and the original one will be mixed. + MethodExecution callee = thisAlias.getMethodExecution(); + callee.setCaller(caller, caller.getStatements().indexOf(otherPrevAlias.getOccurrencePoint().getStatement())); + DummyMethodInvocation dummyInv = new DummyMethodInvocation(callee, caller.getThisClassName(), caller.getThisObjId(), 0, otherPrevAlias.getOccurrencePoint().getStatement().getThreadNo()); + dummyInv.setTimeStamp(callee.getEntryTime()); + DummyTracePoint dummyTp = new DummyTracePoint(caller, dummyInv); + aliasList.add(new Alias(Alias.AliasType.RECEIVER, 0, callee.getThisObjId(), dummyTp)); + } + } } /**