}
private SequenceDiagramModel generateSequenceDiagramModel(
SequenceDiagramContext ctx, Set<MethodInfo> methodStack)
throws NoSuchMethodException, ClassNotFoundException, IOException {
final MethodInfo method = ctx.getMethodInfo();
final ClassInfo classInfo = ctx.getClassInfo();
final String[] filters = ctx.getFilters();
final boolean followMethodCalls = ctx.getFollowInvokedMethods();
// Set used to keep track of which source lines have been shown.
final Set<Integer> sourceLinesShown = new HashSet<Integer>();
sLog.fine("generateSequenceDiagramModel invoked for - "
+ method.toString());
if (methodStack.contains(method)) {
sLog.fine("methodStack contains method. Returning.");
return null;
}
methodStack.add(method);
SequenceDiagramModel model = new SequenceDiagramModel();
model.setTitle(method.toString());
ImmutableActor srcActor = new ImmutableActor(method.getClassName()
.replace('.', '_'), CommonUtils.getClassNameSansPackage(method
.getClassName())
+ "." + method.getMethodName());
model.addActor(srcActor);
List<Instruction> code = classInfo.getMethodCode(method);
LineNumberTable lineNumberTable = classInfo.getLineNumberTable(method);
LineNumber[] lineNumbers = null;
if (lineNumberTable != null) {
lineNumbers = lineNumberTable.getLineNumberTable();
}
for (Instruction line : code) {
if (line instanceof InvokeInstruction) {
sLog.fine("InvokeInstruction - " + line.toString());
InvokeInstruction destInvokeInstruction = (InvokeInstruction) line;
final String invokedClassName = destInvokeInstruction
.getInvokedClass();
// Check if this is a class of interest.
if (filters != null) {
if (!checkPackageMatch(filters, invokedClassName)) {
sLog
.fine("Returning, since this class is not interesting.");
continue;
}
}
final ImmutableActor destActor = new ImmutableActor(
generateSequenceDiagramActorRef(destInvokeInstruction),
CommonUtils
.getClassNameSansPackage(destInvokeInstruction
.getInvokedClass())
+ "."
+ destInvokeInstruction.getInvokedMethod());
model.addMessage(new ImmutableMessage(srcActor, destActor,
generateSequenceDiagramMessage(destInvokeInstruction),
destInvokeInstruction.getInvokedMethodReturnType()));
// Experimentally, at this point, add a sequence diagram model
// for the destActor's invoked method.
if (followMethodCalls) {
sLog.fine(" method calls");
try {
MethodInfo destMethod = new MethodInfo(
invokedClassName, destInvokeInstruction
.getInvokedMethod(),
Utility.methodSignatureArgumentTypes(
destInvokeInstruction
.getInvokedMethodSignature(),
false),
Utility.methodSignatureReturnType(
destInvokeInstruction
.getInvokedMethodSignature(),
false), null);
if (!methodStack.contains(destMethod)) {
// methodStack.add(destMethod);
sLog.info("Following - "
+ destMethod.getClassName() + "."
+ destMethod.getMethodName());
SequenceDiagramContext ctx2 = new SequenceDiagramContext();
ctx2.setClassInfo(new ClassInfo(invokedClassName,
getClassLoader()));
ctx2.setFilters(ctx.getFilters());