blob: 838dadcaf61c02d953e6ff608063ef51bdadf99c [file] [log] [blame]
package org.eclipse.jdt.internal.debug.core;
import java.util.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.debug.core.IJavaDebugConstants;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.request.EventRequest;
import com.sun.jdi.request.MethodEntryRequest;
public class MethodEntryBreakpoint extends LineBreakpoint {
static String fMarkerType= IJavaDebugConstants.JAVA_METHOD_ENTRY_BREAKPOINT;
/**
* Key used to store the class name attribute pertinent to a
* specific method entry request. Used for method entry breakpoints.
*/
public final static String CLASS_NAME= "className";
/**
* Key used to store the name and signature
* attribute pertinent to a specific method
* entry request breakpoint. Used for method entry breakpoints.
*/
public final static String BREAKPOINT_INFO= "breakpointInfo";
/**
* Create a method entry breakpoint on the given marker
*/
public MethodEntryBreakpoint(IMarker marker) {
fMarker= marker;
}
/**
* Creates and returns a method entry breakpoint in the
* given method.
* If hitCount is > 0, the breakpoint will suspend execution when it is
* "hit" the specified number of times. Note: the breakpoint is not
* added to the breakpoint manager - it is merely created.
*
* @param method the method in which to suspend on entry
* @param hitCount the number of times the breakpoint will be hit before
* suspending execution - 0 if it should always suspend
* @return a method entry breakpoint
* @exception DebugException if unable to create the breakpoint marker due
* to a lower level exception.
*/
public MethodEntryBreakpoint(final IMethod method, final int hitCount) throws DebugException {
IWorkspaceRunnable wr= new IWorkspaceRunnable() {
public void run(IProgressMonitor monitor) throws CoreException {
// determine the resource to associate the marker with
IResource resource= null;
resource= method.getUnderlyingResource();
if (resource == null) {
resource= method.getJavaProject().getProject();
}
// create the marker
fMarker= resource.createMarker(fMarkerType);
// find the source range if available
int start = -1;
int end = -1;
ISourceRange range = method.getSourceRange();
if (range != null) {
start = range.getOffset();
end = start + range.getLength() - 1;
}
// configure the standard attributes
setLineBreakpointAttributes(getPluginIdentifier(), true, -1, start, end);
// configure the type handle and hit count
setTypeAndHitCount(method.getDeclaringType(), hitCount);
// configure the method handle
setMethod(method);
// configure the marker as a Java marker
Map attributes= getAttributes();
JavaCore.addJavaElementMarkerAttributes(attributes, method);
setAttributes(attributes);
}
};
run(wr);
}
/**
* A method entry breakpoint has been added.
* Create or update the request.
*/
public void addToTarget(JDIDebugTarget target) {
IType type = getBreakpointType();
if (type == null) {
// internalError(ERROR_BREAKPOINT_NO_TYPE);
return;
}
String className = type.getFullyQualifiedName();
MethodEntryRequest request = target.getMethodEntryRequest(className);
if (request == null) {
try {
request= target.getEventRequestManager().createMethodEntryRequest();
request.addClassFilter(className);
request.putProperty(CLASS_NAME, className);
request.putProperty(BREAKPOINT_INFO, new ArrayList(1));
request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
request.putProperty(IDebugConstants.BREAKPOINT_MARKER, new ArrayList(3));
request.putProperty(IJavaDebugConstants.HIT_COUNT, new ArrayList(3));
} catch (VMDisconnectedException e) {
return;
} catch (RuntimeException e) {
logError(e);
return;
}
}
List breakpointInfo= (List)request.getProperty(BREAKPOINT_INFO);
breakpointInfo.add(null);
List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT);
breakpoints.add(this);
List hitCounts = (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
int hitCount = getHitCount();
if (hitCount > 0) {
hitCounts.add(new Integer(hitCount));
} else {
hitCounts.add(null);
}
completeConfiguration(request);
target.installBreakpoint(this, request);
}
/**
* A method entry breakpoint has been changed.
* Update the request.
*/
public void changeForTarget(JDIDebugTarget target) {
MethodEntryRequest request = (MethodEntryRequest)target.getRequest(this);
if (request == null) {
return;
}
// check the enabled state
updateMethodEntryEnabledState(request);
List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT);
int index= breakpoints.indexOf(this);
// update the breakpoints hit count
int newCount = getHitCount();
List hitCounts= (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
if (newCount > 0) {
hitCounts.set(index, new Integer(newCount));
} else {
//back to a regular breakpoint
hitCounts.set(index, null);
}
}
/**
* Update the enabled state of the request associated with this
* method entry breakpoint. Since a request is potentially associated
* with multiple method entry breakpoints, it should be enabled if
* any of them are enabled.
*/
protected void updateMethodEntryEnabledState(MethodEntryRequest request) {
IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
Iterator breakpoints= ((List)request.getProperty(IDebugConstants.BREAKPOINT)).iterator();
boolean requestEnabled= false;
while (breakpoints.hasNext()) {
JavaBreakpoint breakpoint= (JavaBreakpoint)breakpoints.next();
if (breakpoint.isEnabled()) {
requestEnabled = true;
break;
}
}
updateEnabledState0(request, requestEnabled);
}
/**
* @see JavaBreakpoint#removeFromTarget(JDIDebugTarget)
*/
public void removeFromTarget(JDIDebugTarget target) {
MethodEntryRequest request = (MethodEntryRequest)target.getRequest(this);
if (request != null) {
try {
decrementInstallCount();
} catch (CoreException e) {
logError(e);
}
List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT);
int index = breakpoints.indexOf(this);
breakpoints.remove(index);
if (breakpoints.isEmpty()) {
try {
target.getEventRequestManager().deleteEventRequest(request); // disable & remove
} catch (VMDisconnectedException e) {
} catch (RuntimeException e) {
logError(e);
}
} else {
List hitCounts= (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
hitCounts.remove(index);
}
}
}
/**
* Sets the <code>METHOD_HANDLE</code> attribute of this breakpoint, associated
* with the given IMethod.
*/
public void setMethod(IMethod method) throws CoreException {
String handle = method.getHandleIdentifier();
setMethodHandleIdentifier(handle);
}
/**
* Sets the <code>METHOD_HANDLE</code> attribute of this breakpoint.
*/
public void setMethodHandleIdentifier(String identifier) throws CoreException {
setAttribute(IJavaDebugConstants.METHOD_HANDLE, identifier);
}
}