Newer
Older
org.ntlab.reverseDebugger / org.ntlab.reverseDebugger / src / org / ntlab / reverseDebugger / CallStackModel.java
package org.ntlab.reverseDebugger;

import org.ntlab.onlineAccessor.JDIInstanceMethodCaller;
import org.ntlab.traceAnalysisPlatform.tracer.trace.Trace;

import com.sun.jdi.BooleanValue;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.IncompatibleThreadStateException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.InvocationException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.StringReference;
import com.sun.jdi.ThreadReference;
import com.sun.jdi.Value;
import com.sun.jdi.VirtualMachine;

@SuppressWarnings("restriction")
public class CallStackModel {
	private JDIInstanceMethodCaller methodExecutionMc;
	private String threadId;
	private int callLineNo;

	public CallStackModel(VirtualMachine vm, ThreadReference thread, ObjectReference methodExecution, String threadId, int callLineNo) {
		methodExecutionMc = new JDIInstanceMethodCaller(vm, thread, methodExecution);
		this.callLineNo = callLineNo;
	}

	public VirtualMachine getVm() {
		return methodExecutionMc.getVm();
	}
	
	public JDIInstanceMethodCaller getMethodCaller() {
		return methodExecutionMc;
	}

	public String getThreadId() {
		return threadId;
	}
	
	public int getCallLineNo() {
		return callLineNo;
	}
	
	public String getSignature() {
		String signature = "";
		try {
			signature = ((StringReference)methodExecutionMc.callInstanceMethod("getSignature")).value();
		} catch (InvalidTypeException | ClassNotLoadedException
				| InvocationException | IncompatibleThreadStateException e) {
			e.printStackTrace();
		}
		return signature;
	}
	
	public String getCallStackSignature() {
		String signature = "";		
		try {
			signature = getSignature();
			String objectType = ((StringReference)methodExecutionMc.callInstanceMethod("getThisClassName")).value();
			objectType = objectType.substring(objectType.lastIndexOf(".") + 1);
			boolean isConstructor = ((BooleanValue)methodExecutionMc.callInstanceMethod("isConstructor")).value();
			String declaringType = Trace.getDeclaringType(signature, isConstructor);
			declaringType = declaringType.substring(declaringType.lastIndexOf(".") + 1);
			String methodName = Trace.getMethodName(signature);
			String args = "(" + signature.split("\\(")[1];
			
			StringBuilder sb = new StringBuilder();
			sb.append(objectType);
			if (!declaringType.equals(objectType)) {
				sb.append("(" + declaringType + ")");
			}
			sb.append("." + methodName + args);
			signature = sb.toString();
		} catch (InvalidTypeException | ClassNotLoadedException | InvocationException
				| IncompatibleThreadStateException e) {
			e.printStackTrace();
		}
		return signature;
	}
	
	public Value callInstanceMethod(String methodName, Value... args)
			throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException {
		return methodExecutionMc.callInstanceMethod(methodName, args);
	}
}