*** empty log message ***
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaDebugConstants.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaDebugConstants.java
index aea3f56..c8a1f00 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaDebugConstants.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaDebugConstants.java
@@ -21,6 +21,12 @@
public interface IJavaDebugConstants {
/**
+ * Java breakpoint marker type
+ * (value <code>"org.eclipse.jdt.debug.javaBreakpoint"</code>).
+ */
+ public static final String JAVA_BREAKPOINT= "org.eclipse.jdt.debug.javaBreakpoint";
+
+ /**
* Java line breakpoint marker type
* (value <code>"org.eclipse.jdt.debug.javaLineBreakpoint"</code>).
*/
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
index d174ec0..01bca70 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/IJavaThread.java
@@ -8,8 +8,7 @@
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
-import org.eclipse.core.resources.IMarker;
-import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.internal.debug.core.JavaBreakpoint;
/**
* A Java thread is an extension of a regular thread,
@@ -54,7 +53,7 @@
*
* @return breakpoint that caused suspend, or <code>null</code> if none
*/
- IMarker getBreakpoint();
+ JavaBreakpoint getBreakpoint();
/**
* Returns a variable with the given name, or <code>null</code> if
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java
index 3771588..7b3e2e3 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/debug/core/JDIDebugModel.java
@@ -134,303 +134,25 @@
* to a lower level exception.
*/
public static IMarker createLineBreakpoint(IType type, int lineNumber, int charStart, int charEnd, int hitCount) throws DebugException {
- return createLineBreakpointCommon(type, lineNumber, charStart, charEnd, hitCount, IJavaDebugConstants.JAVA_LINE_BREAKPOINT);
- }
-
- /**
- * Creates and returns a run-to-line breakpoint in the
- * given type, at the given line number. If a character range within the
- * line is known, it may be specified by charStart/charEnd. Run-to-line
- * breakpoints have a hit count of 1.
- * Note: the breakpoint is not added to the breakpoint manager
- * - it is merely created.
- *
- * @param type the type in which to create the breakpoint
- * @param lineNumber the lineNumber on which the breakpoint is created - line
- * numbers are 1 based, associated with the compilation unit in which
- * the type is defined
- * @param charStart the first character index associated with the breakpoint,
- * or -1 if unspecified
- * @param charEnd the last character index associated with the breakpoint,
- * or -1 if unspecified
- * @return a run-to-line breakpoint
- * @exception DebugException if unable to create the breakpoint marker due
- * to a lower level exception.
- */
- public static IMarker createRunToLineBreakpoint(IType type, int lineNumber, int charStart, int charEnd) throws DebugException {
- return createLineBreakpointCommon(type, lineNumber, charStart, charEnd, 1, IJavaDebugConstants.JAVA_RUN_TO_LINE_BREAKPOINT);
- }
-
- /**
- * Common method for creating line breakpoints, either 'regular' or 'run to line'
- */
- private static IMarker createLineBreakpointCommon(final IType type, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final String exceptionType) throws DebugException {
-
- fgBreakpoint= null;
-
- IWorkspaceRunnable wr= new IWorkspaceRunnable() {
-
- public void run(IProgressMonitor monitor) throws CoreException {
- IResource resource= null;
- resource= type.getUnderlyingResource();
- if (resource == null) {
- resource= type.getJavaProject().getProject();
- }
-
- // create the marker
- fgBreakpoint= resource.createMarker(exceptionType);
- DebugPlugin.getDefault().getBreakpointManager().configureLineBreakpoint(fgBreakpoint, getPluginIdentifier(), true, lineNumber, charStart, charEnd);
-
- // configure the hit count and type handle
- DebugJavaUtils.setTypeAndHitCount(fgBreakpoint, type, hitCount);
-
- // configure the marker as a Java marker
- Map attributes= fgBreakpoint.getAttributes();
- JavaCore.addJavaElementMarkerAttributes(attributes, type);
- fgBreakpoint.setAttributes(attributes);
- }
- };
-
- try {
- ResourcesPlugin.getWorkspace().run(wr, null);
- } catch (CoreException e) {
- throw new DebugException(e.getStatus());
- }
-
- return fgBreakpoint;
- }
-
- /**
- * Creates and returns an exception breakpoint for the
- * given (throwable) type. Caught and uncaught specify where the exception
- * should cause thread suspensions - that is, in caught and/or uncaught locations.
- * Checked indicates if the given exception is a checked exception.
- * Note: the breakpoint is not added to the breakpoint manager
- * - it is merely created.
- *
- * @param type the exception for which to create the breakpoint
- * @param caught whether to suspend in caught locations
- * @param uncaught whether to suspend in uncaught locations
- * @param checked whether the exception is a checked exception
- * @return an exception breakpoint
- * @exception DebugException if unable to create the breakpoint marker due
- * to a lower level exception.
- */
- public static IMarker createExceptionBreakpoint(final IType exception, final boolean caught, final boolean uncaught, final boolean checked) throws DebugException {
- // determine the resource to associate the marker with
-
- fgBreakpoint= null;
-
- IWorkspaceRunnable wr= new IWorkspaceRunnable() {
-
- public void run(IProgressMonitor monitor) throws CoreException {
- IResource resource= null;
- resource= exception.getUnderlyingResource();
-
- if (resource == null) {
- resource= exception.getJavaProject().getProject();
- }
-
- // if the exception breakpoint already exists in the breakpoint mgr.,
- // just use it
- IMarker existing= findExistingExceptionBreakpoint(exception);
- if (existing != null) {
- fgBreakpoint= existing;
- return;
- }
-
- // create the marker
- fgBreakpoint= resource.createMarker(IJavaDebugConstants.JAVA_EXCEPTION_BREAKPOINT);
- // configure the standard attributes
- DebugPlugin.getDefault().getBreakpointManager().configureBreakpoint(fgBreakpoint, getPluginIdentifier(), true);
- // configure caught, uncaught, checked, and the type attributes
- DebugJavaUtils.configureExceptionBreakpoint(fgBreakpoint, caught, uncaught, checked, exception);
-
- // configure the marker as a Java marker
- Map attributes= fgBreakpoint.getAttributes();
- JavaCore.addJavaElementMarkerAttributes(attributes, exception);
- fgBreakpoint.setAttributes(attributes);
- }
-
- };
-
- try {
- ResourcesPlugin.getWorkspace().run(wr, null);
- } catch (CoreException e) {
- throw new DebugException(e.getStatus());
- }
-
- return fgBreakpoint;
+ return (new LineBreakpoint(type, lineNumber, charStart, charEnd, hitCount, IJavaDebugConstants.JAVA_LINE_BREAKPOINT)).getMarker();
}
- private static IMarker findExistingExceptionBreakpoint(IType type) {
- IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
- IMarker[] allBreakpoints= manager.getBreakpoints(IJavaDebugConstants.JAVA_EXCEPTION_BREAKPOINT);
- for (int i = 0; i < allBreakpoints.length; i++) {
- IMarker bp= allBreakpoints[i];
- if (DebugJavaUtils.getType(bp).equals(type)) {
- return bp;
- }
- }
- return null;
+ public static IBreakpointManager getBreakpointManager() {
+ return DebugPlugin.getDefault().getBreakpointManager();
}
/**
- * Creates and returns a watchpoint on the
- * given field.
- * If hitCount > 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 field the field on which to suspend (on access or modification)
- * @param hitCount the number of times the breakpoint will be hit before
- * suspending execution - 0 if it should always suspend
- * @return a watchpoint
- * @exception DebugException if unable to create the breakpoint marker due
- * to a lower level exception
- */
- public static IMarker createWatchpoint(final IField field, final int hitCount) throws DebugException {
-
- fgBreakpoint= null;
-
- IWorkspaceRunnable wr= new IWorkspaceRunnable() {
-
- public void run(IProgressMonitor monitor) throws CoreException {
-
- IResource resource = null;
- ICompilationUnit compilationUnit = getCompilationUnit(field);
- if (compilationUnit != null) {
- resource = compilationUnit.getUnderlyingResource();
- }
- if (resource == null) {
- resource = field.getJavaProject().getProject();
- }
-
- fgBreakpoint= resource.createMarker(IJavaDebugConstants.JAVA_WATCHPOINT);
-
- // find the source range if available
- int start = -1;
- int stop = -1;
- ISourceRange range = field.getSourceRange();
- if (range != null) {
- start = range.getOffset();
- stop = start + range.getLength() - 1;
- }
- // configure the standard attributes
- DebugPlugin.getDefault().getBreakpointManager().configureLineBreakpoint(fgBreakpoint, getPluginIdentifier(), true, -1, start, stop);
- // configure the type handle and hit count
- DebugJavaUtils.setTypeAndHitCount(fgBreakpoint, field.getDeclaringType(), hitCount);
- // configure the field handle
- DebugJavaUtils.setField(fgBreakpoint, field);
- // configure the access and modification flags to defaults
- DebugJavaUtils.setDefaultAccessAndModification(fgBreakpoint);
- DebugJavaUtils.setAutoDisabled(fgBreakpoint, false);
-
-
- // configure the marker as a Java marker
- Map attributes= fgBreakpoint.getAttributes();
- JavaCore.addJavaElementMarkerAttributes(attributes, field);
- fgBreakpoint.setAttributes(attributes);
- }
- };
-
- try {
- ResourcesPlugin.getWorkspace().run(wr, null);
- } catch (CoreException e) {
- throw new DebugException(e.getStatus());
- }
-
- return fgBreakpoint;
- }
-
- /**
- * Returns the underlying compilation unit of an element.
- */
- public static ICompilationUnit getCompilationUnit(IJavaElement element) {
- if (element instanceof IWorkingCopy) {
- return (ICompilationUnit) ((IWorkingCopy) element).getOriginalElement();
- }
- if (element instanceof ICompilationUnit) {
- return (ICompilationUnit) element;
- }
- IJavaElement parent = element.getParent();
- if (parent != null) {
- return getCompilationUnit(parent);
- }
- return null;
- }
-
- /**
- * 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 static IMarker createMethodEntryBreakpoint(final IMethod method, final int hitCount) throws DebugException {
- // determine the resource to associate the marker with
-
- fgBreakpoint= null;
-
- IWorkspaceRunnable wr= new IWorkspaceRunnable() {
-
- public void run(IProgressMonitor monitor) throws CoreException {
- IResource resource= null;
- resource= method.getUnderlyingResource();
- if (resource == null) {
- resource= method.getJavaProject().getProject();
- }
-
- // create the marker
- fgBreakpoint= resource.createMarker(IJavaDebugConstants.JAVA_METHOD_ENTRY_BREAKPOINT);
-
- // 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
- DebugPlugin.getDefault().getBreakpointManager().configureLineBreakpoint(fgBreakpoint, getPluginIdentifier(), true, -1, start, end);
- // configure the type handle and hit count
- DebugJavaUtils.setTypeAndHitCount(fgBreakpoint, method.getDeclaringType(), hitCount);
-
- // configure the method handle
- DebugJavaUtils.setMethod(fgBreakpoint, method);
-
- // configure the marker as a Java marker
- Map attributes= fgBreakpoint.getAttributes();
- JavaCore.addJavaElementMarkerAttributes(attributes, method);
- fgBreakpoint.setAttributes(attributes);
- }
-
- };
-
- try {
- ResourcesPlugin.getWorkspace().run(wr, null);
- } catch (CoreException e) {
- throw new DebugException(e.getStatus());
- }
-
- return fgBreakpoint;
- }
- /**
* Returns the hit count of the given breakpoint or -1 if the attribute is not set.
*
* @param breakpoint the breakpoint
* @return hit count, or -1
*/
- public static int getHitCount(IMarker breakpoint) {
- return DebugJavaUtils.getHitCount(breakpoint);
+ public static int getHitCount(IMarker marker) {
+ JavaBreakpoint breakpoint= getBreakpoint(marker);
+ if (breakpoint instanceof LineBreakpoint) {
+ return ((LineBreakpoint)breakpoint).getHitCount();
+ }
+ return -1;
}
/**
@@ -440,54 +162,14 @@
* @param hitCount the number of times the breakpoint is hit before suspending execution
* @exception CoreException if an exception occurrs updating the marker
*/
- public static void setHitCount(IMarker breakpoint, int hitCount) throws CoreException {
- DebugJavaUtils.setHitCount(breakpoint, hitCount);
- }
-
- /**
- * Returns the member the given breakpoint is installed in,
- * or <code>null</code> if a member is not determinable.
- *
- * @param breakpoint the breakpoint
- * @return a member, or <code>null</code>
- */
- public static IMember getMember(IMarker breakpoint) {
- try {
- return DebugJavaUtils.getMember(breakpoint);
- } catch (CoreException e) {
- return null;
+ public static void setHitCount(IMarker marker, int hitCount) throws CoreException {
+ JavaBreakpoint breakpoint= getBreakpoint(marker);
+ if (breakpoint instanceof LineBreakpoint) {
+ ((LineBreakpoint) breakpoint).setHitCount(hitCount);
}
}
- /**
- * Returns the method the given breakpoint is installed in
- * or <code>null</code> if breakpoint is not installed in a method.
- *
- * @param breakpoint the breakpoint
- * @return a method, or <code>null</code>
- */
- public static IMethod getMethod(IMarker breakpoint) {
- return DebugJavaUtils.getMethod(breakpoint);
- }
/**
- * Returns the field handle identifier of the given breakpoint
- */
- public static String getFieldHandleIdentifier(IMarker breakpoint) {
- return DebugJavaUtils.getFieldHandleIdentifier(breakpoint);
- }
-
- /**
- * Returns the field the given breakpoint is installed on
- * or <code>null</code> if breakpoint is not installed in a method.
- *
- * @param breakpoint the breakpoint
- * @return a field or <code>null</code>
- */
- public static IField getField(IMarker breakpoint) {
- return DebugJavaUtils.getField(breakpoint);
- }
-
- /**
* Returns the type the given breakpoint is installed in
* or <code>null</code> if breakpoint is not installed in a type. If
* the breakpoint is an exception breakpoint, the type associated with
@@ -497,118 +179,27 @@
* @param breakpoint the breakpoint
* @return a type, or <code>nulll</code>
*/
- public static IType getType(IMarker breakpoint) {
- return DebugJavaUtils.getType(breakpoint);
+ public static IType getType(IMarker marker) {
+ JavaBreakpoint breakpoint= getBreakpoint(marker);
+ if (breakpoint != null) {
+ return breakpoint.getBreakpointType();
+ }
+ return null;
}
+
/**
- * Returns whether the given breakpoint is an exception
- * breakpoint that will suspend in caught locations.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is an exception
- * breakpoint that will suspend in caught locations
+ * Returns the JavaBreakpoint in the breakpoint manager associated
+ * with the given marker. If no such breakpoint exists, returns
+ * <code>null</code>.
*/
- public static boolean isCaught(IMarker breakpoint) {
- return DebugJavaUtils.isCaught(breakpoint);
+ private static JavaBreakpoint getBreakpoint(IMarker marker) {
+ IBreakpoint breakpoint= getBreakpointManager().getBreakpoint(marker);
+ if (breakpoint instanceof JavaBreakpoint) {
+ return (JavaBreakpoint) breakpoint;
+ }
+ return null;
}
- /**
- * Returns whether the given breakpoint is an exception
- * breakpoint for a checked exception.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is an exception
- * breakpoint for a checked exception
- */
- public static boolean isChecked(IMarker breakpoint) {
- return DebugJavaUtils.isChecked(breakpoint);
- }
- /**
- * Returns whether the given breakpoint
- * is an exception breakpoint.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint
- * is an exception breakpoint
- */
- public static boolean isExceptionBreakpoint(IMarker breakpoint) {
- return DebugJavaUtils.isExceptionBreakpoint(breakpoint);
- }
- /**
- * Returns whether the given breakpoint is installed in at least one debug target.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is installed in at least one debug target
- */
- public static boolean isInstalled(IMarker breakpoint) {
- return DebugJavaUtils.isInstalled(breakpoint);
- }
-
- /**
- * Returns whether the given breakpoint is a watchpoint.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is a watchpoint
- */
- public static boolean isWatchpoint(IMarker breakpoint) {
- return DebugJavaUtils.isWatchpoint(breakpoint);
- }
-
- /**
- * Returns whether the given breakpoint
- * is an access watchpoint.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint
- * is an access watchpoint
- */
- public static boolean isAccess(IMarker breakpoint) {
- return DebugJavaUtils.isAccess(breakpoint);
- }
-
- /**
- * Returns whether the given breakpoint
- * is an modificaion watchpoint.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint
- * is an modification watchpoint
- */
- public static boolean isModification(IMarker breakpoint) {
- return DebugJavaUtils.isModification(breakpoint);
- }
-
- public static boolean isAutoDisabled(IMarker breakpoint) {
- return DebugJavaUtils.isAutoDisabled(breakpoint);
- }
- /**
- * Returns whether the given breakpoint is a method entry breakpoint.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is a method entry breakpoint
- */
- public static boolean isMethodEntryBreakpoint(IMarker breakpoint) {
- return DebugJavaUtils.isMethodEntryBreakpoint(breakpoint);
- }
- /**
- * Returns whether the given breakpoint is a run to line breakpoint.
- *
- * @param breakpoint the breakpoint
- * @retrun whether the given breakpoint is a run to line breakpoint
- */
- public static boolean isRunToLineBreakpoint(IMarker breakpoint) {
- return DebugJavaUtils.isRunToLineBreakpoint(breakpoint);
- }
- /**
- * Returns whether the given breakpoint is an exception
- * breakpoint that will suspend in uncaught locations.
- *
- * @param breakpoint the breakpoint
- * @return whether the given breakpoint is an exception
- * breakpoint that will suspend in uncaught locations
- */
- public static boolean isUncaught(IMarker breakpoint) {
- return DebugJavaUtils.isUncaught(breakpoint);
- }
+
}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaResources.properties b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaResources.properties
index 5bf68e7..d98730d 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaResources.properties
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaResources.properties
@@ -12,6 +12,25 @@
jdi.common.couldnt_set_breakpoint=Breakpoint could not be set at or near line number {0}
##############################################################
+# Breakpoint / Marker
+##############################################################
+jdi_marker.label.line=line:
+jdi_marker.label.hitCount=hit count:
+
+jdi_marker.label.exception.format={1}: {0}
+jdi_marker.label.exception.caught=caught
+jdi_marker.label.exception.uncaught=uncaught
+jdi_marker.label.exception.both=caught and uncaught
+
+jdi_marker.label.watchpoint.format={1}: {0}
+jdi_marker.label.watchpoint.access=access
+jdi_marker.label.watchpoint.modification=modification
+jdi_marker.label.watchpoint.both=access and modification
+
+jdi_breakpoint.error.access_watchpoint.not_supported=VM does not support access watchpoints.
+jdi_breakpoint.error.modification_watchpoint.not_supported=VM does not support modification watchpoints.
+
+##############################################################
# JDIDebugTarget
##############################################################
@@ -26,8 +45,6 @@
jdi_debug_target.error.resume.not_supported=VM does not support resume.
jdi_debug_target.error.suspend.not_supported=VM does not support suspend.
jdi_debug_target.error.terminate.not_supported=VM does not support termination.
-jdi_debug_target.error.access_watchpoint.not_supported=VM does not support access watchpoints.
-jdi_debug_target.error.modification_watchpoint.not_supported=VM does not support modification watchpoints.
jdi_debug_target.error.terminate.exception=Exception occurred while terminating VM.
jdi_debug_target.error.get_crc=Exception occurred retrieving CRC
@@ -76,6 +93,18 @@
jdi_thread.error.no_built_state=Project must be built to perform evaluations
jdi_thread.error.invalid_evaluation_location=Unable to perform evaluation at current location. Thread must be suspended by a breakpoint or step.
+jdi_thread.label.exception_sys=System Thread [{0}] (Suspended (exception {1}))
+jdi_thread.label.exception_usr=Thread [{0}] (Suspended (exception {1}))
+jdi_thread.label.line_breakpoint_sys=System Thread [{0}] (Suspended (breakpoint at line {1} in {2}))
+jdi_thread.label.line_breakpoint_usr=Thread [{0}] (Suspended (breakpoint at line {1} in {2}))
+jdi_thread.label.run_to_line_breakpoint_usr=Thread [{0}] (Suspended (run to line line {1} in {2}))
+jdi_thread.label.run_to_line_breakpoint_sys=System Thread [{0}] (Suspended (run to line line {1} in {2}))
+jdi_thread.label.access_sys=System Thread [{0}] (Suspended (access of field {1} in {2}))
+jdi_thread.label.access_usr=Thread [{0}] (Suspended (access of field {1} in {2}))
+jdi_thread.label.modification_sys=System Thread [{0}] (Suspended (modification of field {1} in {2}))
+jdi_thread.label.modification_usr=Thread [{0}] (Suspended (modification of field {1} in {2}))
+jdi_thread.label.run_to_line_sys=System Thread [{0}] (Suspended (run to line {1} in {2}))
+jdi_thread.label.run_to_line_usr=Thread [{0}] (Suspended (run to line {1} in {2}))
##############################################################
# JDIStackFrame
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaUtils.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaUtils.java
index 102f95b..0dae17f 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaUtils.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/DebugJavaUtils.java
Binary files differ
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
index 4af40a4..064469e 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/EventDispatcher.java
@@ -10,9 +10,26 @@
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.IDebugConstants;
+
import com.sun.jdi.ThreadReference;
import com.sun.jdi.VMDisconnectedException;
-import com.sun.jdi.event.*;
+import com.sun.jdi.event.BreakpointEvent;
+import com.sun.jdi.event.ClassPrepareEvent;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.event.EventIterator;
+import com.sun.jdi.event.EventQueue;
+import com.sun.jdi.event.EventSet;
+import com.sun.jdi.event.ExceptionEvent;
+import com.sun.jdi.event.LocatableEvent;
+import com.sun.jdi.event.MethodEntryEvent;
+import com.sun.jdi.event.StepEvent;
+import com.sun.jdi.event.ThreadDeathEvent;
+import com.sun.jdi.event.ThreadStartEvent;
+import com.sun.jdi.event.VMDeathEvent;
+import com.sun.jdi.event.VMDisconnectEvent;
+import com.sun.jdi.event.VMStartEvent;
+import com.sun.jdi.event.WatchpointEvent;
/**
* Dispatches events generated by a debuggable VM.
@@ -61,71 +78,45 @@
if (event instanceof StepEvent) {
dispatchStepEvent((StepEvent)event);
} else
- if (event instanceof BreakpointEvent) {
- dispatchLocatableEvent((LocatableEvent) event);
+ if ((event instanceof BreakpointEvent) ||
+ (event instanceof LocatableEvent) ||
+ (event instanceof ExceptionEvent) ||
+ (event instanceof WatchpointEvent) ||
+ (event instanceof MethodEntryEvent)) {
+ dispatchBreakpointEvent(event);
} else
- if (event instanceof ExceptionEvent) {
- dispatchExceptionEvent((ExceptionEvent) event);
+ if (event instanceof ThreadStartEvent) {
+ fTarget.handleThreadStart((ThreadStartEvent) event);
} else
- if (event instanceof ThreadStartEvent) {
- fTarget.handleThreadStart((ThreadStartEvent) event);
+ if (event instanceof ThreadDeathEvent) {
+ fTarget.handleThreadDeath((ThreadDeathEvent) event);
} else
- if (event instanceof ThreadDeathEvent) {
- fTarget.handleThreadDeath((ThreadDeathEvent) event);
+ if (event instanceof ClassPrepareEvent) {
+ fTarget.handleClassLoad((ClassPrepareEvent) event);
} else
- if (event instanceof ClassPrepareEvent) {
- fTarget.handleClassLoad((ClassPrepareEvent) event);
+ if (event instanceof VMDeathEvent) {
+ fTarget.handleVMDeath((VMDeathEvent) event);
+ fKeepReading= false; // stop listening for events
} else
- if (event instanceof WatchpointEvent) {
- dispatchLocatableEvent((LocatableEvent) event);
- } else
- if (event instanceof MethodEntryEvent) {
- fTarget.handleMethodEntry((MethodEntryEvent) event);
- } else
- if (event instanceof VMDeathEvent) {
- fTarget.handleVMDeath((VMDeathEvent) event);
- fKeepReading= false; // stop listening for events
- } else
- if (event instanceof VMDisconnectEvent) {
- fTarget.handleVMDisconnect((VMDisconnectEvent) event);
- fKeepReading= false; // stop listening for events
- } else if (event instanceof VMStartEvent) {
- fTarget.handleVMStart((VMStartEvent)event);
- } else {
- // Unknown Event Type
- }
+ if (event instanceof VMDisconnectEvent) {
+ fTarget.handleVMDisconnect((VMDisconnectEvent) event);
+ fKeepReading= false; // stop listening for events
+ } else if (event instanceof VMStartEvent) {
+ fTarget.handleVMStart((VMStartEvent)event);
+ } else {
+ // Unknown Event Type
+ }
}
}
-
- protected void dispatchLocatableEvent(LocatableEvent event) {
+
+ protected void dispatchBreakpointEvent(Event event) {
if (!fKeepReading) {
return;
}
- ThreadReference threadRef= event.thread();
- JDIThread thread= findThread(threadRef);
- if (thread == null) {
- fTarget.resume(threadRef);
- return;
- } else {
- thread.handleLocatableEvent(event);
- }
+ JavaBreakpoint breakpoint= (JavaBreakpoint)event.request().getProperty(IDebugConstants.BREAKPOINT);
+ breakpoint.handleEvent(event, fTarget);
}
- protected void dispatchExceptionEvent(ExceptionEvent event) {
- if (!fKeepReading) {
- return;
- }
- ThreadReference threadRef= event.thread();
- JDIThread thread= findThread(threadRef);
- if (thread == null) {
- fTarget.resume(threadRef);
- return;
- } else {
- thread.handleException((ExceptionEvent) event);
- }
- }
-
-
protected void dispatchStepEvent(StepEvent event) {
ThreadReference threadRef= event.thread();
JDIThread thread= findThread(threadRef);
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java
new file mode 100644
index 0000000..b8aa7ad
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/ExceptionBreakpoint.java
@@ -0,0 +1,368 @@
+package org.eclipse.jdt.internal.debug.core;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.IDebugConstants;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.event.ExceptionEvent;
+import com.sun.jdi.request.EventRequest;
+import com.sun.jdi.request.ExceptionRequest;
+
+public class ExceptionBreakpoint extends JavaBreakpoint {
+
+ // Thread label String keys
+ private static final String EXCEPTION_SYS= THREAD_LABEL + "exception_sys";
+ private static final String EXCEPTION_USR= THREAD_LABEL + "exception_usr";
+ // Marker label String keys
+ protected final static String EXCEPTION= MARKER_LABEL + "exception.";
+ protected final static String FORMAT= EXCEPTION + "format";
+ protected final static String CAUGHT= EXCEPTION + "caught";
+ protected final static String UNCAUGHT= EXCEPTION + "uncaught";
+ protected final static String BOTH= EXCEPTION + "both";
+ // Attribute strings
+ protected static final String[] fgExceptionBreakpointAttributes= new String[]{IJavaDebugConstants.CHECKED, IJavaDebugConstants.TYPE_HANDLE};
+
+ static String fMarkerType= IJavaDebugConstants.JAVA_EXCEPTION_BREAKPOINT;
+
+ public ExceptionBreakpoint(IMarker marker) {
+ super(marker);
+ }
+
+ /**
+ * Creates and returns an exception breakpoint for the
+ * given (throwable) type. Caught and uncaught specify where the exception
+ * should cause thread suspensions - that is, in caught and/or uncaught locations.
+ * Checked indicates if the given exception is a checked exception.
+ * Note: the breakpoint is not added to the breakpoint manager
+ * - it is merely created.
+ *
+ * @param type the exception for which to create the breakpoint
+ * @param caught whether to suspend in caught locations
+ * @param uncaught whether to suspend in uncaught locations
+ * @param checked whether the exception is a checked exception
+ * @return an exception breakpoint
+ * @exception DebugException if unable to create the breakpoint marker due
+ * to a lower level exception.
+ */
+ public ExceptionBreakpoint(final IType exception, final boolean caught, final boolean uncaught, final boolean checked) throws DebugException {
+ IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IResource resource= null;
+ resource= exception.getUnderlyingResource();
+
+ if (resource == null) {
+ resource= exception.getJavaProject().getProject();
+ }
+
+ // create the marker
+ fMarker= resource.createMarker(fMarkerType);
+ // configure the standard attributes
+ configure(getPluginIdentifier(), true);
+ // configure caught, uncaught, checked, and the type attributes
+ setDefaultCaughtAndUncaught();
+ configureExceptionBreakpoint(checked, exception);
+
+ // configure the marker as a Java marker
+ Map attributes= getAttributes();
+ JavaCore.addJavaElementMarkerAttributes(attributes, exception);
+ setAttributes(attributes);
+ }
+
+ };
+ run(wr);
+ }
+
+ /**
+ * Sets the <code>CAUGHT</code>, <code>UNCAUGHT</code>, <code>CHECKED</code> and
+ * <code>TYPE_HANDLE</code> attributes of the given exception breakpoint.
+ */
+ public void configureExceptionBreakpoint(boolean checked, IType exception) throws CoreException {
+ String handle = exception.getHandleIdentifier();
+ Object[] values= new Object[]{new Boolean(checked), handle};
+ setAttributes(fgExceptionBreakpointAttributes, values);
+ }
+
+ public void setDefaultCaughtAndUncaught() {
+ Object[] values= new Object[]{Boolean.TRUE, Boolean.TRUE};
+ String[] attributes= new String[]{IJavaDebugConstants.CAUGHT, IJavaDebugConstants.UNCAUGHT};
+ try {
+ setAttributes(attributes, values);
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+
+ /**
+ * @see JavaBreakpoint#installIn(JDIDebugTarget)
+ */
+ public void addToTarget(JDIDebugTarget target) {
+ fTarget= target;
+ changeForTarget(target);
+ }
+
+ /**
+ * An exception breakpoint has changed
+ */
+ public void changeForTarget(JDIDebugTarget target) {
+
+ boolean caught= isCaught();
+ boolean uncaught= isUncaught();
+
+ if (caught || uncaught) {
+ IType exceptionType = getBreakpointType();
+ if (exceptionType == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+ String exceptionName = exceptionType.getFullyQualifiedName();
+ String topLevelName = getTopLevelTypeName();
+ if (topLevelName == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+ List classes= target.jdiClassesByName(exceptionName);
+ ReferenceType exClass= null;
+ if (classes != null && !classes.isEmpty()) {
+ exClass= (ReferenceType) classes.get(0);
+ }
+ if (exClass == null) {
+ // defer the exception
+ target.defer(this, topLevelName);
+ } else {
+ // new or changed - first delete the old request
+ if (null != target.getRequest(this))
+ removeFromTarget(target);
+ ExceptionRequest request= null;
+ try {
+ request= target.getEventRequestManager().createExceptionRequest(exClass, caught, uncaught);
+ request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
+ request.putProperty(IDebugConstants.BREAKPOINT, this);
+ } catch (VMDisconnectedException e) {
+ return;
+ } catch (RuntimeException e) {
+ logError(e);
+ return;
+ }
+ request.setEnabled(isEnabled());
+ target.installBreakpoint(this, request);
+ }
+ } else {
+ removeFromTarget(target);
+ }
+ }
+
+ /**
+ * An exception breakpoint has been removed
+ */
+ public void removeFromTarget(JDIDebugTarget target) {
+ IType type = getBreakpointType();
+ if (type == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+ String name = type.getFullyQualifiedName();
+ ExceptionRequest request= (ExceptionRequest) target.uninstallBreakpoint(this);
+ if (request != null) {
+ try {
+ target.getEventRequestManager().deleteEventRequest(request);
+ } catch (VMDisconnectedException e) {
+ return;
+ } catch (RuntimeException e) {
+ logError(e);
+ return;
+ }
+ }
+ List deferred = target.getDeferredBreakpointsByClass(name);
+ if (deferred != null) {
+ deferred.remove(this);
+ if (deferred.isEmpty()) {
+ target.removeDeferredBreakpointByClass(name);
+ }
+ }
+ }
+
+ /**
+ * @see JavaBreakpoint#handleEvent(Event)
+ */
+ public void handleEvent(Event event, JDIDebugTarget target){
+ if (!(event instanceof ExceptionEvent)) {
+ return;
+ }
+ ThreadReference threadRef= ((ExceptionEvent)event).thread();
+ JDIThread thread= target.findThread(threadRef);
+ if (thread == null) {
+ target.resume(threadRef);
+ return;
+ } else {
+ thread.handleSuspendForBreakpoint(this);
+ }
+ }
+
+ /**
+ * @see JavaBreakpoint#isSupportedBy(VirtualMachine)
+ */
+ public boolean isSupportedBy(VirtualMachine vm) {
+ return true;
+ }
+
+ /**
+ * Enable this exception breakpoint.
+ *
+ * If the exception breakpoint is not catching caught or uncaught,
+ * set the default values. If this isn't done, the resulting
+ * state (enabled with caught and uncaught both disabled)
+ * is ambiguous.
+ */
+ public void enable() {
+ if (!(isCaught() || isUncaught())) {
+ setDefaultCaughtAndUncaught();
+ }
+ super.enable();
+ }
+
+ /**
+ * Toggle the caught state of this breakpoint
+ */
+ public void toggleCaught() throws CoreException {
+ setCaught(!isCaught());
+ }
+
+ /**
+ * Returns the <code>CAUGHT</code> attribute of the given breakpoint
+ * or <code>false</code> if the attribute is not set.
+ */
+ public boolean isCaught() {
+ return getBooleanAttribute(IJavaDebugConstants.CAUGHT);
+ }
+
+ /**
+ * Sets the <code>CAUGHT</code> attribute of the given breakpoint.
+ */
+ public void setCaught(boolean caught) throws CoreException {
+ if (caught == isCaught()) {
+ return;
+ }
+ try {
+ setBooleanAttribute(IJavaDebugConstants.CAUGHT, caught);
+ if (caught && !isEnabled()) {
+ enable();
+ } else if (!(caught || isUncaught())) {
+ disable();
+ }
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ if (fTarget != null) {
+ // Notify the target that this watchpoint has changed
+ changeForTarget(fTarget);
+ }
+ }
+
+ /**
+ * Toggle the caught state of this breakpoint
+ */
+ public void toggleUncaught() throws CoreException {
+ setUncaught(!isUncaught());
+ }
+
+ /**
+ * Returns the <code>UNCAUGHT</code> attribute of the given breakpoint
+ * or <code>false</code> if the attribute is not set.
+ */
+ public boolean isUncaught() {
+ return getBooleanAttribute(IJavaDebugConstants.UNCAUGHT);
+ }
+
+ /**
+ * Sets the <code>UNCAUGHT</code> attribute of the given breakpoint.
+ */
+ public void setUncaught(boolean uncaught) throws CoreException {
+
+ if (uncaught == isUncaught()) {
+ return;
+ }
+ try {
+ setBooleanAttribute(IJavaDebugConstants.UNCAUGHT, uncaught);
+ if (uncaught && !isEnabled()) {
+ enable();
+ } else if (!(uncaught || isCaught())) {
+ disable();
+ }
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ if (fTarget != null) {
+ // Notify the target that this watchpoint has changed
+ changeForTarget(fTarget);
+ }
+ }
+
+ /**
+ * Returns whether the given breakpoint represents a checked exception.
+ */
+ public boolean isChecked() {
+ return getBooleanAttribute(IJavaDebugConstants.CHECKED);
+ }
+
+ /**
+ * Sets the <code>CHECKED</code> attribute of the given breakpoint.
+ */
+ public void setChecked(boolean checked) throws CoreException {
+ setBooleanAttribute(IJavaDebugConstants.CHECKED, checked);
+ }
+
+ /**
+ * @see JavaBreakpoint
+ */
+ public String getFormattedThreadText(String threadName, String typeName, boolean systemThread) {
+ if (systemThread) {
+ return getFormattedString(EXCEPTION_SYS, new String[] {threadName, typeName});
+ }
+ return getFormattedString(EXCEPTION_USR, new String[] {threadName, typeName});
+ }
+
+ /**
+ */
+ public String getMarkerText(boolean showQualified) {
+ String name;
+ if (showQualified) {
+ name= getBreakpointType().getFullyQualifiedName();
+ } else {
+ name= getBreakpointType().getElementName();
+ }
+
+ String state= null;
+ boolean c= isCaught();
+ boolean u= isUncaught();
+ if (c && u) {
+ state= BOTH;
+ } else if (c) {
+ state= CAUGHT;
+ } else if (u) {
+ state= UNCAUGHT;
+ }
+ String label= null;
+ if (state == null) {
+ label= name;
+ } else {
+ String format= DebugJavaUtils.getResourceString(FORMAT);
+ state= DebugJavaUtils.getResourceString(state);
+ label= MessageFormat.format(format, new Object[] {state, name});
+ }
+ return label;
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
index 7517235..f16e0c9 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
@@ -5,14 +5,10 @@
* All Rights Reserved.
*/
-import org.eclipse.debug.core.DebugPlugin;
-import org.eclipse.debug.core.IDebugConstants;
-import org.eclipse.debug.core.ILaunchManager;
-import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.core.resources.*;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPluginDescriptor;
-import org.eclipse.core.runtime.Plugin;
+import org.eclipse.core.runtime.*;
+import org.eclipse.debug.core.*;
+import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.jdt.debug.core.IJavaDebugConstants;
/**
@@ -44,24 +40,26 @@
public void startup() throws CoreException {
fJavaHCRMgr= new JavaHotCodeReplaceManager();
- fJavaHCRMgr.startup();
+ fJavaHCRMgr.startup();
- IMarker[] breakpoints= null;
+ IMarker[] markers= null;
IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
try {
- breakpoints= root.findMarkers(IJavaDebugConstants.JAVA_LINE_BREAKPOINT, true, IResource.DEPTH_INFINITE);
+ markers= root.findMarkers(IJavaDebugConstants.JAVA_LINE_BREAKPOINT, true, IResource.DEPTH_INFINITE);
} catch (CoreException e) {
DebugJavaUtils.logError(e);
return;
}
-
- if (breakpoints == null) {
+ if (markers == null) {
return;
}
-
- for (int i = 0; i < breakpoints.length; i++) {
- IMarker breakpoint = breakpoints[i];
- DebugJavaUtils.configureBreakpointAtStartup(breakpoint);
+
+ IBreakpointManager manager= DebugPlugin.getDefault().getBreakpointManager();
+ for (int i= 0; i < markers.length; i++) {
+ JavaBreakpoint breakpoint= (JavaBreakpoint)manager.loadMarker(markers[i]);
+ if (breakpoint != null) {
+ breakpoint.configureBreakpointAtStartup();
+ }
}
}
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugTarget.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugTarget.java
index 9e4fab3..9b1ad20 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugTarget.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugTarget.java
@@ -5,21 +5,20 @@
* All Rights Reserved.
*/
-import com.sun.jdi.*;
+import java.io.ByteArrayInputStream;
+import java.util.*;
+
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.*;
import org.eclipse.debug.core.model.*;
import org.eclipse.jdt.core.*;
import org.eclipse.jdt.core.eval.IEvaluationContext;
-import org.eclipse.jdt.debug.core.IJavaDebugConstants;
-import org.eclipse.jdt.debug.core.IJavaDebugTarget;
-import org.eclipse.jdt.debug.core.JDIDebugModel;
+import org.eclipse.jdt.debug.core.*;
+
+import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
-import java.io.ByteArrayInputStream;
-import java.text.MessageFormat;
-import java.util.*;
/**
* Debug target for JDI debug model.
@@ -41,25 +40,12 @@
private final static String ERROR_RESUME_NOT_SUPPORTED = ERROR + "resume.not_supported";
private final static String ERROR_SUSPEND_NOT_SUPPORTED = ERROR + "suspend.not_supported";
private final static String ERROR_TERMINATE_NOT_SUPPORTED = ERROR + "terminate.not_supported";
- private final static String ERROR_ACCESS_WATCHPOINT_NOT_SUPPORTED = ERROR + "access.not_supported";
- private final static String ERROR_MODIFICATION_WATCHPOINT_NOT_SUPPORTED = ERROR + "modification.net_supported";
private final static String ERROR_TERMINATE = ERROR + "terminate.exception";
private static final String ERROR_GET_CRC= ERROR + "get_crc";
private static final int MAX_THREAD_DEATH_ATTEMPTS = 1;
/**
- * Key used to store the class name attribute pertinent to a
- * specific method entry request. Used for method entry breakpoints.
- */
- protected 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.
- */
- protected final static String BREAKPOINT_INFO= "breakpointInfo";
- /**
* Associated system process, or <code>null</code> if not available.
*/
protected IProcess fProcess;
@@ -84,8 +70,8 @@
* corresponding class is not yet loaded).
* <p>
* Key: the fully qualified name of the class
- * Value: a <code>List</code> of <code>IMarker</code>s representing the
- * deferred breakpointsin that class.
+ * Value: a <code>List</code> of <code>JavaBreakpoint</code>s representing the
+ * deferred breakpoints in that class.
*/
protected Map fDeferredBreakpointsByClass;
/**
@@ -98,9 +84,8 @@
/**
* Table of installed breakpoints
* <p>
- * Key: breakpoint (<code>IMarker</code>)
- * Value: the event request associated with the breakpoint (one
- * of <code>BreakpointRequest</code> or <code>MethodEntryRequest</code>).
+ * Key: breakpoint (<code>JavaBreakpoint</code>)
+ * Value: the event request associated with the breakpoint (<code>Object</code>).
*/
protected HashMap fInstalledBreakpoints;
@@ -263,9 +248,11 @@
* Installs all breakpoints that currently exist in the breakpoint manager
*/
protected void initializeBreakpoints() {
- IMarker[] bps = getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
+ IBreakpoint[] bps = (IBreakpoint[]) getBreakpointManager().getBreakpoints(JDIDebugModel.getPluginIdentifier());
for (int i = 0; i < bps.length; i++) {
- breakpointAdded(bps[i]);
+ if (bps[i] instanceof JavaBreakpoint) {
+ breakpointAdded((JavaBreakpoint)bps[i]);
+ }
}
}
@@ -403,7 +390,7 @@
* @param breakpoint the breakpoint to defer
* @param typeName name of the type the given breakpoint is associated with
*/
- protected void defer(IMarker breakpoint, String typeName) {
+ protected void defer(JavaBreakpoint breakpoint, String typeName) {
List bps= (List) fDeferredBreakpointsByClass.get(typeName);
if (bps == null) {
// listen for the load of the type
@@ -595,99 +582,6 @@
createThreadDeathInstance(threadRef);
resume(threadRef);
}
-
- /**
- * Handles a method entry event. If this method entry event is
- * in a method that a method entry breakpoint has been set for,
- * handle the event as a breakpoint.
- */
- protected void handleMethodEntry(MethodEntryEvent event) {
- Method enteredMethod = event.method();
- MethodEntryRequest request = (MethodEntryRequest)event.request();
- List breakpoints = (List)request.getProperty(IDebugConstants.BREAKPOINT_MARKER);
- Iterator requestBreakpoints= breakpoints.iterator();
- IMarker breakpoint= null;
- int index= 0;
- while (requestBreakpoints.hasNext()) {
- IMarker aBreakpoint= (IMarker)requestBreakpoints.next();
- Object[] nameSignature= getMethodEntryBreakpointInfo(request, aBreakpoint, index);
- String enteredMethodName= enteredMethod.name();
- if (nameSignature != null && nameSignature[0].equals(enteredMethodName) &&
- nameSignature[1].equals(enteredMethod.signature())) {
- breakpoint= aBreakpoint;
- break;
- }
- index++;
- }
- if (breakpoint == null) {
- handleMethodEntryResume(event.thread());
- return;
- }
-
- List counts = (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
- Integer count= (Integer)counts.get(index);
- if (count != null) {
- handleHitCountMethodEntryBreakpoint(event, breakpoint, counts, count, index);
- } else {
- // no hit count - suspend
- handleMethodEntryBreakpoint(event.thread(), breakpoint);
- }
- }
-
- protected void handleMethodEntryResume(ThreadReference thread) {
- if (!hasPendingEvents()) {
- resume(thread);
- }
- }
-
- protected void handleHitCountMethodEntryBreakpoint(MethodEntryEvent event, IMarker breakpoint, List counts, Integer count, int index) {
- // decrement count and suspend if 0
- int hitCount = count.intValue();
- if (hitCount > 0) {
- hitCount--;
- count = new Integer(hitCount);
- counts.set(index, count);
- if (hitCount == 0) {
- // the count has reached 0, breakpoint hit
- handleMethodEntryBreakpoint(event.thread(), breakpoint);
- try {
- // make a note that we auto-disabled the breakpoint
- // order is important here...see methodEntryChanged
- DebugJavaUtils.setExpired(breakpoint, true);
- getBreakpointManager().setEnabled(breakpoint, false);
- } catch (CoreException e) {
- internalError(e);
- }
- } else {
- // count still > 0, keep running
- handleMethodEntryResume(event.thread());
- }
- } else {
- // hit count expired, keep running
- handleMethodEntryResume(event.thread());
- }
- }
- protected String[] getMethodEntryBreakpointInfo(MethodEntryRequest request, IMarker breakpoint, int index) {
- List nameSignatures = (List)request.getProperty(BREAKPOINT_INFO);
- if (nameSignatures.get(index) != null) {
- return (String[])nameSignatures.get(index);
- }
- String[] nameSignature= new String[2];
- IMethod aMethod= DebugJavaUtils.getMethod(breakpoint);
- try {
- if (aMethod.isConstructor()) {
- nameSignature[0]= "<init>";
- } else {
- nameSignature[0]= aMethod.getElementName();
- }
- nameSignature[1]= aMethod.getSignature();
- nameSignatures.add(index, nameSignature);
- return nameSignature;
- } catch (JavaModelException e) {
- logError(e);
- return null;
- }
- }
/**
* Resumes the given thread
@@ -701,9 +595,9 @@
}
}
- protected void handleMethodEntryBreakpoint(ThreadReference thread, IMarker breakpoint) {
+ protected void handleMethodEntryBreakpoint(ThreadReference thread, JavaBreakpoint breakpoint) {
JDIThread jdiThread = findThread(thread);
- jdiThread.handleSuspendMethodEntry(breakpoint);
+ jdiThread.handleSuspendForBreakpoint(breakpoint);
}
/**
* Handles a thread death event.
@@ -742,107 +636,51 @@
terminate0();
}
- /**
- * Returns the top-level type name associated with the type
- * the given breakpoint is associated with, or <code>null</code>.
- */
- protected String getTopLevelTypeName(IMarker breakpoint) {
- IType type = DebugJavaUtils.getType(breakpoint);
- if (type != null) {
- while (type.getDeclaringType() != null) {
- type = type.getDeclaringType();
- }
- return type.getFullyQualifiedName();
- }
- return null;
- }
-
+
/**
* Installs or defers the given breakpoint
*/
- public void breakpointAdded(IMarker breakpoint) {
- if (DebugJavaUtils.isExceptionBreakpoint(breakpoint)) {
- exceptionBreakpointAdded(breakpoint);
- } else if (DebugJavaUtils.isMethodEntryBreakpoint(breakpoint)) {
- methodEntryBreakpointAdded(breakpoint);
- } else if (DebugJavaUtils.isWatchpoint(breakpoint)) {
- watchpointAdded(breakpoint);
- } else {
- lineBreakpointAdded(breakpoint);
- }
+ public void breakpointAdded(IBreakpoint breakpoint) {
+ breakpoint.addToTarget(this);
}
- protected void lineBreakpointAdded(IMarker breakpoint) {
- String topLevelName= getTopLevelTypeName(breakpoint);
- if (topLevelName == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
-
- // look for the top-level class - if it is loaded, inner classes may also be loaded
- List classes= jdiClassesByName(topLevelName);
- if (classes == null || classes.isEmpty()) {
- // defer
- defer(breakpoint, topLevelName);
- } else {
- // try to install
- ReferenceType type= (ReferenceType) classes.get(0);
- if (!installLineBreakpoint(breakpoint, type)) {
- // install did not succeed - could be an inner type not yet loaded
- defer(breakpoint, topLevelName);
- }
- }
+ /**
+ * Add a breakpoint to the installed breakpoints collection
+ */
+ public void installBreakpoint(JavaBreakpoint breakpoint, Object request) {
+ fInstalledBreakpoints.put(breakpoint, request);
}
/**
- * Installs a line breakpoint in the given type, returning whether successful.
+ * Remove a breakpoint from the installed breakpoints collection
*/
- protected boolean installLineBreakpoint(IMarker marker, ReferenceType type) {
- Location location= null;
- IBreakpointManager manager= getBreakpointManager();
- int lineNumber= manager.getLineNumber(marker);
- location= determineLocation(lineNumber, type);
- if (location == null) {
- // could be an inner type not yet loaded, or line information not available
- return false;
- }
-
- if (createLineBreakpointRequest(location, marker) != null) {
- // update the install attibute on the breakpoint
- if (!fInHCR) {
- try {
- DebugJavaUtils.incrementInstallCount(marker);
- } catch (CoreException e) {
- internalError(e);
- }
- }
- return true;
- } else {
- return false;
- }
-
+ public Object uninstallBreakpoint(JavaBreakpoint breakpoint) {
+ return fInstalledBreakpoints.remove(breakpoint);
}
/**
- * Creates, installs, and returns a line breakpoint request at
- * the given location for the given breakpoint.
+ * Return the request object associated with the given breakpoint
*/
- protected BreakpointRequest createLineBreakpointRequest(Location location, IMarker breakpoint) {
- BreakpointRequest request = null;
- try {
- request= getEventRequestManager().createBreakpointRequest(location);
- configureRequest(request, breakpoint);
- } catch (VMDisconnectedException e) {
- fInstalledBreakpoints.remove(breakpoint);
- return null;
- } catch (RuntimeException e) {
- fInstalledBreakpoints.remove(breakpoint);
- internalError(e);
- return null;
- }
- request.setEnabled(getBreakpointManager().isEnabled(breakpoint));
- fInstalledBreakpoints.put(breakpoint, request);
- return request;
+ public Object getRequest(JavaBreakpoint breakpoint) {
+ return fInstalledBreakpoints.get(breakpoint);
+ }
+
+ /**
+ * Return the deferred breakpoints
+ */
+ public List getDeferredBreakpointsByClass(String name) {
+ return (List)fDeferredBreakpointsByClass.get(name);
+ }
+
+ /**
+ * Remove a deferred breakpoint
+ */
+ public void removeDeferredBreakpointByClass(String name) {
+ fDeferredBreakpointsByClass.remove(name);
+ }
+
+ public boolean inHCR() {
+ return fInHCR;
}
/**
@@ -900,424 +738,8 @@
/**
* @see IBreakpointSupport
*/
- public void breakpointChanged(IMarker breakpoint, IMarkerDelta delta) {
- if (DebugJavaUtils.isExceptionBreakpoint(breakpoint)) {
- exceptionBreakpointChanged(breakpoint);
- } else if (DebugJavaUtils.isMethodEntryBreakpoint(breakpoint)) {
- methodEntryBreakpointChanged(breakpoint, delta);
- } else if (DebugJavaUtils.isWatchpoint(breakpoint)) {
- watchpointChanged(breakpoint);
- } else {
- lineBreakpointChanged(breakpoint);
- }
- }
-
- protected void lineBreakpointChanged(IMarker breakpoint) {
- EventRequest request= (BreakpointRequest) fInstalledBreakpoints.get(breakpoint);
- if (request != null) {
- // already installed - could be a change in the enabled state or hit count
- //may result in a new request being generated
- request= updateHitCount(request, breakpoint);
- if (request != null) {
- updateEnabledState(request, breakpoint);
- fInstalledBreakpoints.put(breakpoint, request);
- }
- }
- }
-
- protected void updateMethodEntryEnabledState(MethodEntryRequest request) {
- IBreakpointManager manager= getBreakpointManager();
- Iterator breakpoints= ((List)request.getProperty(IDebugConstants.BREAKPOINT_MARKER)).iterator();
- boolean requestEnabled= false;
- while (breakpoints.hasNext()) {
- IMarker breakpoint= (IMarker)breakpoints.next();
- if (manager.isEnabled(breakpoint)) {
- requestEnabled = true;
- break;
- }
- }
- updateEnabledState0(request, requestEnabled);
- }
-
- protected void updateEnabledState(EventRequest request, IMarker breakpoint) {
- updateEnabledState0(request, getBreakpointManager().isEnabled(breakpoint));
-
- }
-
- private void updateEnabledState0(EventRequest request, boolean enabled) {
- if (request.isEnabled() != enabled) {
- // change the enabled state
- try {
- // if the request has expired, and is not a method entry request, do not disable.
- // BreakpointRequests that have expired cannot be deleted. However method entry
- // requests that are expired can be deleted (since we simulate the hit count)
- if (request instanceof MethodEntryRequest || !isExpired(request)) {
- request.setEnabled(enabled);
- }
- } catch (VMDisconnectedException e) {
- } catch (RuntimeException e) {
- internalError(e);
- }
- }
- }
-
- /**
- * Update the hit count of an <code>EventRequest</code>. Return a new request with
- * the appropriate settings.
- */
- protected EventRequest updateHitCount(EventRequest request, IMarker marker) {
-
- // if the hit count has changed, or the request has expired and is being re-enabled,
- // create a new request
- if (hasHitCountChanged(marker, request) || (isExpired(request) && getBreakpointManager().isEnabled(marker))) {
- try {
- // delete old request
- //on JDK you cannot delete (disable) an event request that has hit its count filter
- if (!isExpired(request)) {
- getEventRequestManager().deleteEventRequest(request); // disable & remove
- }
- if (request instanceof BreakpointRequest) {
- Location location = ((BreakpointRequest) request).location();
- request = createLineBreakpointRequest(location, marker);
- } else {
- Field field= ((WatchpointRequest) request).field();
- if (request instanceof AccessWatchpointRequest) {
- request= createAccessWatchpoint(marker, field);
- } else if (request instanceof ModificationWatchpointRequest) {
- request= createModificationWatchpoint(marker, field);
- }
- }
- } catch (VMDisconnectedException e) {
- } catch (RuntimeException e) {
- internalError(e);
- }
- }
- return request;
- }
-
- /**
- * Returns whether the hitCount of a marker is equal to the hitCount of
- * the associated request.
- */
- protected boolean hasHitCountChanged(IMarker marker, EventRequest request) {
- int hitCount= DebugJavaUtils.getHitCount(marker);
- Integer requestCount= (Integer) request.getProperty(IJavaDebugConstants.HIT_COUNT);
- int oldCount = -1;
- if (requestCount != null) {
- oldCount = requestCount.intValue();
- }
- return hitCount != oldCount;
- }
-
- /**
- * An exception breakpoint has been added.
- */
- protected void exceptionBreakpointAdded(IMarker exceptionBreakpoint) {
- exceptionBreakpointChanged(exceptionBreakpoint);
- }
-
- /**
- * An exception breakpoint has changed
- */
- protected void exceptionBreakpointChanged(IMarker exceptionBreakpoint) {
-
- boolean caught= DebugJavaUtils.isCaught(exceptionBreakpoint);
- boolean uncaught= DebugJavaUtils.isUncaught(exceptionBreakpoint);
-
- if (caught || uncaught) {
- IType exceptionType = DebugJavaUtils.getType(exceptionBreakpoint);
- if (exceptionType == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- String exceptionName = exceptionType.getFullyQualifiedName();
- String topLevelName = getTopLevelTypeName(exceptionBreakpoint);
- if (topLevelName == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- List classes= jdiClassesByName(exceptionName);
- ReferenceType exClass= null;
- if (classes != null && !classes.isEmpty()) {
- exClass= (ReferenceType) classes.get(0);
- }
- if (exClass == null) {
- // defer the exception
- defer(exceptionBreakpoint, topLevelName);
- } else {
- // new or changed - first delete the old request
- if (null != fInstalledBreakpoints.get(exceptionBreakpoint))
- exceptionBreakpointRemoved(exceptionBreakpoint);
- ExceptionRequest request= null;
- try {
- request= getEventRequestManager().createExceptionRequest(exClass, caught, uncaught);
- configureRequest(request, exceptionBreakpoint);
- } catch (VMDisconnectedException e) {
- return;
- } catch (RuntimeException e) {
- internalError(e);
- return;
- }
- request.setEnabled(getBreakpointManager().isEnabled(exceptionBreakpoint));
- fInstalledBreakpoints.put(exceptionBreakpoint, request);
- }
- } else {
- exceptionBreakpointRemoved(exceptionBreakpoint);
- }
- }
-
- /**
- * An exception breakpoint has been removed
- */
- protected void exceptionBreakpointRemoved(IMarker exceptionBreakpoint) {
- IType type = DebugJavaUtils.getType(exceptionBreakpoint);
- if (type == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- String name = type.getFullyQualifiedName();
- ExceptionRequest request= (ExceptionRequest) fInstalledBreakpoints.remove(exceptionBreakpoint);
- if (request != null) {
- try {
- getEventRequestManager().deleteEventRequest(request);
- } catch (VMDisconnectedException e) {
- return;
- } catch (RuntimeException e) {
- internalError(e);
- return;
- }
- }
- List deferred = (List)fDeferredBreakpointsByClass.get(name);
- if (deferred != null) {
- deferred.remove(exceptionBreakpoint);
- if (deferred.isEmpty()) {
- fDeferredBreakpointsByClass.remove(name);
- }
- }
- }
-
- /**
- * A watchpoint has been added.
- * Create or update the request.
- */
- protected void watchpointAdded(IMarker breakpoint) {
- selectiveWatchpointAdded(breakpoint, true, true);
-
- }
-
- /**
- * A single watchpoint can create multiple requests. This method provides control over this
- * property for explicitly choosing which requests (access, modification, or both) to
- * potentially add.
- */
- protected void selectiveWatchpointAdded(IMarker breakpoint, boolean accessCheck, boolean modificationCheck) {
- String topLevelName= getTopLevelTypeName(breakpoint);
- if (topLevelName == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
-
- List classes= jdiClassesByName(topLevelName);
- if (classes == null || classes.isEmpty()) {
- // defer
- defer(breakpoint, topLevelName);
- return;
- }
-
- IField javaField= DebugJavaUtils.getField(breakpoint);
- Field field= null;
- ReferenceType reference= null;
- for (int i=0; i<classes.size(); i++) {
- reference= (ReferenceType) classes.get(i);
- field= reference.fieldByName(javaField.getElementName());
- if (field == null) {
- return;
- }
- AccessWatchpointRequest accessRequest= null;
- ModificationWatchpointRequest modificationRequest= null;
- // If we're not supposed to check access or modification, just retrieve the
- // existing request
- if (!accessCheck) {
- accessRequest= getAccessWatchpointRequest(field);
- }
- if (!modificationCheck) {
- modificationRequest= getModificationWatchpointRequest(field);
- }
- if (DebugJavaUtils.isAccess(breakpoint) && accessCheck) {
- if (getVM().canWatchFieldAccess()) {
- accessRequest= accessWatchpointAdded(breakpoint, field);
- } else {
- try {
- notSupported(ERROR_ACCESS_WATCHPOINT_NOT_SUPPORTED);
- } catch (DebugException e) {
- internalError(e);
- }
- }
- }
- if (DebugJavaUtils.isModification(breakpoint) && modificationCheck) {
- if (getVM().canWatchFieldModification()) {
- modificationRequest= modificationWatchpointAdded(breakpoint, field);
- } else {
- try {
- notSupported(ERROR_MODIFICATION_WATCHPOINT_NOT_SUPPORTED);
- } catch (DebugException e) {
- internalError(e);
- }
- }
- }
- if (!(accessRequest == null && modificationRequest == null)) {
- Object[] requests= {accessRequest, modificationRequest};
- fInstalledBreakpoints.put(breakpoint, requests);
- try {
- DebugJavaUtils.incrementInstallCount(breakpoint);
- } catch (CoreException e) {
- internalError(e);
- }
- }
- }
- }
-
- /**
- * An access watchpoint has been added.
- * Create or update the request.
- */
- protected AccessWatchpointRequest accessWatchpointAdded(IMarker breakpoint, Field field) {
- AccessWatchpointRequest request= getAccessWatchpointRequest(field);
- if (request == null) {
- request= createAccessWatchpoint(breakpoint, field);
- }
- // Important: Enable only after request has been configured
- request.setEnabled(getBreakpointManager().isEnabled(breakpoint));
- return request;
- }
-
- /**
- * Create an access watchpoint for the given breakpoint and associated field
- */
- protected AccessWatchpointRequest createAccessWatchpoint(IMarker breakpoint, Field field) {
- AccessWatchpointRequest request= null;
- try {
- request= getEventRequestManager().createAccessWatchpointRequest(field);
- configureRequest(request, breakpoint);
- } catch (VMDisconnectedException e) {
- return null;
- } catch (RuntimeException e) {
- internalError(e);
- return null;
- }
- return request;
- }
-
- /**
- * A modification watchpoint has been added.
- * Create or update the request.
- */
- protected ModificationWatchpointRequest modificationWatchpointAdded(IMarker breakpoint, Field field) {
- ModificationWatchpointRequest request= getModificationWatchpointRequest(field);
- if (request == null) {
- request= createModificationWatchpoint(breakpoint, field);
- }
- // Important: only enable a request after it has been configured
- request.setEnabled(getBreakpointManager().isEnabled(breakpoint));
- return request;
- }
-
- /**
- * Create a modification watchpoint for the given breakpoint and associated field
- */
- protected ModificationWatchpointRequest createModificationWatchpoint(IMarker breakpoint, Field field) {
- ModificationWatchpointRequest request= null;
- try {
- request= getEventRequestManager().createModificationWatchpointRequest(field);
- configureRequest(request, breakpoint);
- } catch (VMDisconnectedException e) {
- return null;
- } catch (RuntimeException e) {
- internalError(e);
- return null;
- }
- return request;
- }
-
- /**
- * Configure a request with common properties:
- * <ul>
- * <li><code>IDebugConstants.BREAKPOINT_MARKER</code></li>
- * <li><code>IJavaDebugConstants.HIT_COUNT</code></li>
- * <li><code>IJavaDebugConstants.EXPIRED</code></li>
- * </ul>
- * and sets the suspend policy of the request to suspend the event thread.
- */
- protected void configureRequest(EventRequest request, IMarker breakpoint) {
- request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
- request.putProperty(IDebugConstants.BREAKPOINT_MARKER, breakpoint);
- int hitCount= DebugJavaUtils.getHitCount(breakpoint);
- if (hitCount > 0) {
- request.addCountFilter(hitCount);
- request.putProperty(IJavaDebugConstants.HIT_COUNT, new Integer(hitCount));
- request.putProperty(IJavaDebugConstants.EXPIRED, Boolean.FALSE);
- }
- }
-
- /**
- * Enable a request and increment the install count of the associated breakpoint.
- */
- protected void completeConfiguration(EventRequest request, IMarker breakpoint) {
- // Important: Enable only after request has been configured
- request.setEnabled(getBreakpointManager().isEnabled(breakpoint));
- try {
- DebugJavaUtils.incrementInstallCount(breakpoint);
- } catch (CoreException e) {
- internalError(e);
- }
- }
-
- /**
- * A method entry breakpoint has been added.
- * Create or update the request.
- */
- protected void methodEntryBreakpointAdded(IMarker breakpoint) {
- IType type = DebugJavaUtils.getType(breakpoint);
- if (type == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- String className = type.getFullyQualifiedName();
-
- MethodEntryRequest request = getMethodEntryRequest(className);
-
- if (request == null) {
- try {
- request= 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) {
- internalError(e);
- return;
- }
- }
- List breakpointInfo= (List)request.getProperty(BREAKPOINT_INFO);
- breakpointInfo.add(null);
-
- List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT_MARKER);
- breakpoints.add(breakpoint);
-
-
- List hitCounts = (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
- int hitCount = DebugJavaUtils.getHitCount(breakpoint);
- if (hitCount > 0) {
- hitCounts.add(new Integer(hitCount));
- } else {
- hitCounts.add(null);
- }
- completeConfiguration(request, breakpoint);
- fInstalledBreakpoints.put(breakpoint, request);
+ public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta delta) {
+ breakpoint.changeForTarget(this);
}
/**
@@ -1356,152 +778,18 @@
Iterator requests= getEventRequestManager().methodEntryRequests().iterator();
while (requests.hasNext()) {
MethodEntryRequest existingRequest= (MethodEntryRequest)requests.next();
- if (className.equals(existingRequest.getProperty(CLASS_NAME))) {
+ if (className.equals(existingRequest.getProperty(MethodEntryBreakpoint.CLASS_NAME))) {
return existingRequest;
}
}
return null;
}
-
- /**
- * A watchpoint has been changed.
- * Update the request.
- */
- protected void watchpointChanged(IMarker breakpoint) {
- Object[] requests= (Object[])fInstalledBreakpoints.get(breakpoint);
- for (int i=0; i < requests.length; i++) {
- WatchpointRequest request= (WatchpointRequest)requests[i];
- if (request == null) {
- if ((i == 0) && DebugJavaUtils.isAccess(breakpoint)) {
- selectiveWatchpointAdded(breakpoint, true, false);
- }
- if ((i == 1) && DebugJavaUtils.isModification(breakpoint)) {
- selectiveWatchpointAdded(breakpoint, false, true);
- }
- continue;
- }
- if ((!DebugJavaUtils.isAccess(breakpoint) && (request instanceof AccessWatchpointRequest)) ||
- (!DebugJavaUtils.isModification(breakpoint) && (request instanceof ModificationWatchpointRequest))) {
- getEventRequestManager().deleteEventRequest(request); // disable & remove
- continue;
- }
- request= (WatchpointRequest)updateHitCount(request, breakpoint);
-
- if (request != null) {
- updateEnabledState(request, breakpoint);
- requests[i]= request;
- }
- }
- }
-
- /**
- * A method entry breakpoint has been changed.
- * Update the request.
- */
- protected void methodEntryBreakpointChanged(IMarker breakpoint, IMarkerDelta delta) {
- MethodEntryRequest request = (MethodEntryRequest)fInstalledBreakpoints.get(breakpoint);
- if (request == null) {
- return;
- }
- // check the enabled state
- updateMethodEntryEnabledState(request);
-
- List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT_MARKER);
- int index= breakpoints.indexOf(breakpoint);
- // update the breakpoints hit count
- int newCount = DebugJavaUtils.getHitCount(breakpoint);
- 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);
- }
- }
-
- /**
- * A watchpoint has been removed.
- * Remove the request.
- */
- protected void watchpointRemoved(IMarker breakpoint) {
- Object[] requests= (Object[]) fInstalledBreakpoints.remove(breakpoint);
- if (requests == null) {
- //deferred breakpoint
- if (!breakpoint.exists()) {
- //resource no longer exists
- return;
- }
- String name= getTopLevelTypeName(breakpoint);
- if (name == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- List markers= (List) fDeferredBreakpointsByClass.get(name);
- if (markers == null) {
- return;
- }
-
- markers.remove(breakpoint);
- if (markers.isEmpty()) {
- fDeferredBreakpointsByClass.remove(name);
- }
- } else {
- //installed breakpoint
- try {
- for (int i=0; i<requests.length; i++) {
- WatchpointRequest request= (WatchpointRequest)requests[i];
- if (request == null) {
- continue;
- }
- getEventRequestManager().deleteEventRequest(request); // disable & remove
- }
- try {
- DebugJavaUtils.decrementInstallCount(breakpoint);
- } catch (CoreException e) {
- internalError(e);
- }
- } catch (VMDisconnectedException e) {
- return;
- } catch (RuntimeException e) {
- internalError(e);
- }
- }
- }
-
- /**
- * A method entry breakpoint has been removed.
- * Update the request.
- */
- protected void methodEntryBreakpointRemoved(IMarker breakpoint) {
- MethodEntryRequest request = (MethodEntryRequest)fInstalledBreakpoints.remove(breakpoint);
- if (request != null) {
- try {
- DebugJavaUtils.decrementInstallCount(breakpoint);
- } catch (CoreException e) {
- internalError(e);
- }
- List breakpoints= (List)request.getProperty(IDebugConstants.BREAKPOINT_MARKER);
- int index = breakpoints.indexOf(breakpoint);
- breakpoints.remove(index);
- if (breakpoints.isEmpty()) {
- try {
- getEventRequestManager().deleteEventRequest(request); // disable & remove
- } catch (VMDisconnectedException e) {
- } catch (RuntimeException e) {
- internalError(e);
- }
- } else {
- List hitCounts= (List)request.getProperty(IJavaDebugConstants.HIT_COUNT);
- hitCounts.remove(index);
- }
- }
- }
/**
* @see IBreakpointSupport
*/
- public boolean supportsBreakpoint(IMarker breakpoint) {
- return !isTerminated() && !isDisconnected() && JDIDebugModel.getPluginIdentifier().equals(getBreakpointManager().getModelIdentifier(breakpoint));
+ public boolean supportsBreakpoint(IBreakpoint breakpoint) {
+ return !isTerminated() && !isDisconnected() && JDIDebugModel.getPluginIdentifier().equals(breakpoint.getModelIdentifier());
}
/**
@@ -1575,15 +863,15 @@
//inner class load...resolve the top level type name
topLevelName= className.substring(0, index);
}
- ArrayList markers= (ArrayList) fDeferredBreakpointsByClass.remove(topLevelName);
- if (markers != null) {
+ ArrayList breakpoints= (ArrayList) fDeferredBreakpointsByClass.remove(topLevelName);
+ if (breakpoints != null) {
//no longer need to listen for this class load
ClassPrepareRequest request= (ClassPrepareRequest) fClassPrepareRequestsByClass.remove(topLevelName);
getEventRequestManager().deleteEventRequest(request);
- Iterator itr= ((ArrayList) markers.clone()).iterator();
+ Iterator itr= ((ArrayList) breakpoints.clone()).iterator();
while (itr.hasNext()) {
- IMarker marker= (IMarker) itr.next();
- breakpointAdded(marker);
+ JavaBreakpoint breakpoint= (JavaBreakpoint) itr.next();
+ breakpoint.addToTarget(this);
}
}
}
@@ -1592,11 +880,11 @@
* Sets all the breakpoints to be uninstalled.
*/
protected void uninstallAllBreakpoints() {
- Iterator markers= ((Map)((HashMap)fInstalledBreakpoints).clone()).keySet().iterator();
- while (markers.hasNext()) {
- IMarker marker= (IMarker) markers.next();
+ Iterator breakpoints= ((Map)((HashMap)fInstalledBreakpoints).clone()).keySet().iterator();
+ while (breakpoints.hasNext()) {
+ JavaBreakpoint breakpoint= (JavaBreakpoint) breakpoints.next();
try {
- DebugJavaUtils.decrementInstallCount(marker);
+ breakpoint.decrementInstallCount();
} catch (CoreException e) {
internalError(e);
}
@@ -1607,53 +895,8 @@
/**
* @see IBreakpointSupport
*/
- public void breakpointRemoved(IMarker breakpoint, IMarkerDelta delta) {
- if (DebugJavaUtils.isExceptionBreakpoint(breakpoint)) {
- exceptionBreakpointRemoved(breakpoint);
- } else if (DebugJavaUtils.isMethodEntryBreakpoint(breakpoint)) {
- methodEntryBreakpointRemoved(breakpoint);
- } else if (DebugJavaUtils.isWatchpoint(breakpoint)) {
- watchpointRemoved(breakpoint);
- } else {
- lineBreakpointRemoved(breakpoint);
- }
- }
-
- protected void lineBreakpointRemoved(IMarker breakpoint) {
- BreakpointRequest request= (BreakpointRequest) fInstalledBreakpoints.remove(breakpoint);
- if (request == null) {
- //deferred breakpoint
- if (!breakpoint.exists()) {
- //resource no longer exists
- return;
- }
- String name= getTopLevelTypeName(breakpoint);
- if (name == null) {
- internalError(ERROR_BREAKPOINT_NO_TYPE);
- return;
- }
- List markers= (List) fDeferredBreakpointsByClass.get(name);
- if (markers == null) {
- return;
- }
-
- markers.remove(breakpoint);
- if (markers.isEmpty()) {
- fDeferredBreakpointsByClass.remove(name);
- }
- } else {
- //installed breakpoint
- try {
- // cannot delete an expired request
- if (!isExpired(request)) {
- getEventRequestManager().deleteEventRequest(request); // disable & remove
- }
- } catch (VMDisconnectedException e) {
- return;
- } catch (RuntimeException e) {
- internalError(e);
- }
- }
+ public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta delta) {
+ breakpoint.removeFromTarget(this);
}
/**
@@ -1666,16 +909,9 @@
while (itr.hasNext()) {
// do not notify the breakpoint manager of uninstall, as we
// are in a resource change callback and cannot modify the resource tree
- IMarker marker= (IMarker) itr.next();
- boolean watchpointMarker= false;
- try {
- watchpointMarker= marker.isSubtypeOf(IJavaDebugConstants.JAVA_WATCHPOINT);
- } catch (CoreException ce) {
- logError(ce);
- continue;
- }
- if (watchpointMarker) {
- Object[] requests= (Object[])fInstalledBreakpoints.remove(marker);
+ JavaBreakpoint breakpoint= (JavaBreakpoint) itr.next();
+ if (breakpoint instanceof Watchpoint) {
+ Object[] requests= (Object[])fInstalledBreakpoints.remove(breakpoint);
for (int i=0; i<requests.length; i++) {
EventRequest req = (EventRequest)requests[i];
if (req != null) {
@@ -1683,10 +919,10 @@
}
}
} else {
- EventRequest req = (EventRequest)fInstalledBreakpoints.remove(marker);
+ EventRequest req = (EventRequest)fInstalledBreakpoints.remove(breakpoint);
getEventRequestManager().deleteEventRequest(req);
}
- breakpointAdded(marker);
+ breakpoint.addToTarget(this);
}
}
}
@@ -1755,29 +991,6 @@
}
return null;
}
-
- /**
- * Called by a JDI thread when a breakpoint or
- * watchpoint is encountered.
- */
- public void expireHitCount(LocatableEvent event) {
- EventRequest request= (EventRequest)event.request();
- Integer requestCount= (Integer) request.getProperty(IJavaDebugConstants.HIT_COUNT);
- if (requestCount != null) {
- IMarker breakpoint= (IMarker)request.getProperty(IDebugConstants.BREAKPOINT_MARKER);
- if (breakpoint == null) {
- return;
- }
- try {
- request.putProperty(IJavaDebugConstants.EXPIRED, Boolean.TRUE);
- getBreakpointManager().setEnabled(breakpoint, false);
- // make a note that we auto-disabled this breakpoint.
- DebugJavaUtils.setExpired(breakpoint, true);
- } catch (CoreException ce) {
- internalError(ce);
- }
- }
- }
/**
* @see IDebugElement
@@ -1792,7 +1005,7 @@
*
* @see IAdaptable
*/
- protected Object getAdpater(Class adapter) {
+ public Object getAdapter(Class adapter) {
if (adapter == IJavaDebugTarget.class) {
return this;
}
@@ -1903,18 +1116,7 @@
}
return context;
}
-
- /**
- * Returns whether the given request is expired
- */
- protected boolean isExpired(EventRequest request) {
- Boolean requestExpired= (Boolean) request.getProperty(IJavaDebugConstants.EXPIRED);
- if (requestExpired == null) {
- return false;
- }
- return requestExpired.booleanValue();
- }
-
+
/**
* The JDIDebugPlugin is shutting down.
* Shutdown the event dispatcher.
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java
index 8cb02c1..cf6f26f 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIThread.java
@@ -109,7 +109,7 @@
* The breakpoint that caused the last suspend, or
* <code>null</code> if none.
*/
- protected IMarker fCurrentBreakpoint;
+ protected JavaBreakpoint fCurrentBreakpoint;
/**
* The cached named of the underlying thread.
@@ -137,7 +137,6 @@
* invocations cannot be performed.
*/
protected boolean fInEvaluation = false;
- protected boolean fEvaluationAborted = false;
/**
* Creates a new thread on the underlying thread reference.
@@ -191,7 +190,7 @@
/**
* @see IJavaThread
*/
- public IMarker getBreakpoint() {
+ public JavaBreakpoint getBreakpoint() {
if (fCurrentBreakpoint != null && !fCurrentBreakpoint.exists()) {
fCurrentBreakpoint= null;
}
@@ -444,24 +443,10 @@
}
invokeComplete(timeout);
- if (fEvaluationAborted) {
- fEvaluationAborted = false;
- resume();
- }
return result;
}
/**
- * Called by JDIValue when an evaluation of
- * #toString times out. Causes this thread to
- * be automatically resumed when it returns from
- * its evaluation - see <code>invokeMethod</code>.
- */
- protected void abortEvaluation() {
- fEvaluationAborted = true;
- }
-
- /**
* Invokes a method in this thread, creating a new instance of the given
* class using the specified constructor, and returns the result.
*/
@@ -595,24 +580,11 @@
*/
protected void handleLocatableEvent(LocatableEvent event) {
abortDropAndStep();
- fCurrentBreakpoint= (IMarker) event.request().getProperty(IDebugConstants.BREAKPOINT_MARKER);
+ fCurrentBreakpoint= (JavaBreakpoint) event.request().getProperty(IDebugConstants.BREAKPOINT);
setRunning(false, DebugEvent.BREAKPOINT);
- ((JDIDebugTarget) getDebugTarget()).expireHitCount(event);
}
- /**
- * Suspend the thread based on an exception event
- */
- protected void handleException(ExceptionEvent event) {
- abortDropAndStep();
- fCurrentBreakpoint= (IMarker) event.request().getProperty(IDebugConstants.BREAKPOINT_MARKER);
- setRunning(false, DebugEvent.BREAKPOINT);
- }
-
- /**
- * Suspend the thread based on the method entry event
- */
- protected void handleSuspendMethodEntry(IMarker breakpoint) {
+ protected void handleSuspendForBreakpoint(JavaBreakpoint breakpoint) {
abortDropAndStep();
fCurrentBreakpoint= breakpoint;
setRunning(false, DebugEvent.BREAKPOINT);
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIValue.java
index aa1e95c..c2c76ef 100644
--- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIValue.java
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIValue.java
Binary files differ
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java
new file mode 100644
index 0000000..7c0adf8
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpoint.java
@@ -0,0 +1,383 @@
+package org.eclipse.jdt.internal.debug.core;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.*;
+import org.eclipse.debug.core.model.IDebugTarget;
+import org.eclipse.debug.internal.core.Breakpoint;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+import com.sun.jdi.VMDisconnectedException;
+import com.sun.jdi.VirtualMachine;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.request.EventRequest;
+import com.sun.jdi.request.MethodEntryRequest;
+
+public abstract class JavaBreakpoint extends Breakpoint {
+
+ // Thread and marker label resource String keys
+ protected static final String THREAD_PREFIX= "jdi_thread.";
+ protected static final String MARKER_PREFIX= "jdi_marker.";
+ protected static final String LABEL= "label.";
+ protected static final String THREAD_LABEL= THREAD_PREFIX + LABEL;
+ protected static final String MARKER_LABEL= MARKER_PREFIX + LABEL;
+ /**
+ * JavaBreakpoint attributes
+ */
+ protected static final String[] fgExpiredEnabledAttributes= new String[]{IJavaDebugConstants.EXPIRED, IDebugConstants.ENABLED};
+
+ protected JDIDebugTarget fTarget= null;
+
+ public JavaBreakpoint() {
+ }
+
+ public JavaBreakpoint(IMarker marker) {
+ super(marker);
+ }
+
+ /**
+ * @see Breakpoint#addToTarget(IDebugTarget)
+ */
+ public void addToTarget(IDebugTarget target) {
+ if (target instanceof JDIDebugTarget) {
+ addToTarget((JDIDebugTarget) target);
+ }
+ }
+
+ /**
+ * This breakpoint is being added to the target
+ * Create or update the request.
+ */
+ public abstract void addToTarget(JDIDebugTarget target);
+
+ /**
+ * @see Breakpoint#changeForTarget
+ */
+ public void changeForTarget(IDebugTarget target) {
+ if (target instanceof JDIDebugTarget) {
+ changeForTarget((JDIDebugTarget) target);
+ }
+ }
+
+ /**
+ * This breakpoint has been changed.
+ * Update the request from the given target.
+ */
+ public abstract void changeForTarget(JDIDebugTarget target);
+
+ /**
+ * @see Breakpoint#removeFromTarget(IDebugTarget)
+ */
+ public void removeFromTarget(IDebugTarget target) {
+ if (target instanceof JDIDebugTarget) {
+ removeFromTarget((JDIDebugTarget) target);
+ }
+ }
+
+ /**
+ * This breakpoint has been removed.
+ * Remove the request from the given target.
+ */
+ public abstract void removeFromTarget(JDIDebugTarget target);
+
+ /**
+ * Update the enabled state of the given request, which is associated
+ * with this breakpoint. Set the enabled state of the request
+ * to the enabled state of this breakpoint.
+ */
+ protected void updateEnabledState(EventRequest request) {
+ updateEnabledState0(request, this.isEnabled());
+ }
+
+ /**
+ * Set the enabled state of the given request as specified by the enabled
+ * parameter
+ */
+ protected void updateEnabledState0(EventRequest request, boolean enabled) {
+ if (request.isEnabled() != enabled) {
+ // change the enabled state
+ try {
+ // if the request has expired, and is not a method entry request, do not disable.
+ // BreakpointRequests that have expired cannot be deleted. However method entry
+ // requests that are expired can be deleted (since we simulate the hit count)
+ if (request instanceof MethodEntryRequest || !isExpired(request)) {
+ request.setEnabled(enabled);
+ }
+ } catch (VMDisconnectedException e) {
+ } catch (RuntimeException e) {
+ logError(e);
+ }
+ }
+ }
+
+ /**
+ * Returns whether this kind of breakpoint is supported by the given
+ * virtual machine.
+ */
+ public abstract boolean isSupportedBy(VirtualMachine vm);
+
+ /**
+ * Return whether this breakpoint is enabled
+ */
+ public boolean isEnabled() {
+ try {
+ return super.isEnabled();
+ } catch (CoreException ce) {
+ logError(ce);
+ return false;
+ }
+ }
+
+ /**
+ * Returns whether this breakpoint has expired.
+ */
+ public boolean isExpired() {
+ return getBooleanAttribute(IJavaDebugConstants.EXPIRED);
+ }
+
+ /**
+ * Returns whether the given request is expired
+ */
+ protected boolean isExpired(EventRequest request) {
+ Boolean requestExpired= (Boolean) request.getProperty(IJavaDebugConstants.EXPIRED);
+ if (requestExpired == null) {
+ return false;
+ }
+ return requestExpired.booleanValue();
+ }
+
+ /**
+ * An event request has been fired for this breakpoint. Handle it.
+ */
+ public abstract void handleEvent(Event event, JDIDebugTarget target);
+
+ /**
+ * Enable this breakpoint
+ */
+ public void enable() {
+ try {
+ super.enable();
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+
+ /**
+ * Disable this breakpoint
+ */
+ public void disable() {
+ try {
+ super.disable();
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+
+ /**
+ * Returns whether this breakpoint is installed in at least
+ * one debug target.
+ */
+ public boolean isInstalled() {
+ return getAttribute(IJavaDebugConstants.INSTALL_COUNT, 0) > 0;
+ }
+
+ /**
+ * Increments the install count on this breakpoint
+ */
+ public void incrementInstallCount() throws CoreException {
+ int count = getInstallCount();
+ setAttribute(IJavaDebugConstants.INSTALL_COUNT, count + 1);
+ }
+
+ /**
+ * Returns the <code>INSTALL_COUNT</code> attribute of this breakpoint
+ * or 0 if the attribute is not set.
+ */
+ public int getInstallCount() {
+ return getAttribute(IJavaDebugConstants.INSTALL_COUNT, 0);
+ }
+
+ /**
+ * Decrements the install count on this breakpoint. If the new
+ * install count is 0, the <code>EXPIRED</code> attribute is reset to
+ * <code>false</code> (since any hit count breakpoints that auto-expired
+ * should be re-enabled when the debug session is over).
+ */
+ public void decrementInstallCount() throws CoreException {
+ int count= getInstallCount();
+ if (count > 0) {
+ setAttribute(IJavaDebugConstants.INSTALL_COUNT, count - 1);
+ }
+ if (count == 1) {
+ if (isExpired()) {
+ // if breakpoint was auto-disabled, re-enable it
+ setAttributes(fgExpiredEnabledAttributes,
+ new Object[]{Boolean.FALSE, Boolean.TRUE});
+ }
+ }
+ }
+
+ /**
+ * Sets the <code>TYPE_HANDLE</code> attribute of the given breakpoint, associated
+ * with the given IType.
+ */
+ public void setType(IType type) throws CoreException {
+ String handle = type.getHandleIdentifier();
+ setTypeHandleIdentifier(handle);
+ }
+
+ /**
+ * Sets the <code>TYPE_HANDLE</code> attribute of the given breakpoint.
+ */
+ public void setTypeHandleIdentifier(String identifier) throws CoreException {
+ setAttribute(IJavaDebugConstants.TYPE_HANDLE, identifier);
+ }
+
+ /**
+ * Returns the type the given breakpoint is installed in
+ * or <code>null</code> a type cannot be resolved.
+ */
+ public IType getBreakpointType() {
+ try {
+ String handle = getTypeHandleIdentifier();
+ if (handle != null) {
+ return (IType)JavaCore.create(handle);
+ }
+ } catch (CoreException e) {
+ logError(e);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <code>TYPE_HANDLE</code> attribute of the given breakpoint.
+ */
+ public String getTypeHandleIdentifier() throws CoreException {
+ return (String)getAttribute(IJavaDebugConstants.TYPE_HANDLE);
+ }
+
+ /**
+ * Returns the top-level type name associated with the type
+ * the given breakpoint is associated with, or <code>null</code>.
+ */
+ public String getTopLevelTypeName() {
+ IType type = getBreakpointType();
+ if (type != null) {
+ while (type.getDeclaringType() != null) {
+ type = type.getDeclaringType();
+ }
+ return type.getFullyQualifiedName();
+ }
+ return null;
+ }
+
+ /**
+ * Returns the text that should be displayed on a thread when the
+ * breakpoint is hit.
+ */
+ public String getThreadText(String threadName, boolean qualified, boolean systemThread) {
+ String typeName= getBreakpointTypeName(qualified);
+ return getFormattedThreadText(threadName, typeName, systemThread);
+ }
+
+ /**
+ * Returns the formatted text that should be displayed on a thread
+ * when the breakpoint is hit.
+ */
+ public abstract String getFormattedThreadText(String threadName, String typeName, boolean systemThread);
+
+ public String getBreakpointTypeName(boolean qualified) {
+ String typeName= "";
+ typeName= getBreakpointType().getFullyQualifiedName();
+ if (!qualified) {
+ int index= typeName.lastIndexOf('.');
+ if (index != -1) {
+ typeName= typeName.substring(index + 1);
+ }
+ }
+ return typeName;
+ }
+
+ /**
+ * Returns the identifier for this JDI debug model plug-in
+ *
+ * @return plugin identifier
+ */
+ public static String getPluginIdentifier() {
+ return JDIDebugPlugin.getDefault().getDescriptor().getUniqueIdentifier();
+ }
+
+ /**
+ * Plug in the single argument to the resource String for the key to get a formatted resource String
+ */
+ public static String getFormattedString(String key, String arg) {
+ return getFormattedString(key, new String[] {arg});
+ }
+
+ /**
+ * Plug in the arguments to the resource String for the key to get a formatted resource String
+ */
+ public static String getFormattedString(String key, String[] args) {
+ String string= DebugJavaUtils.getResourceString(key);
+ return MessageFormat.format(string, args);
+ }
+
+ /**
+ * Returns the VM this breakpoint is contained in
+ * or <code>null</code> if it is not installed.
+ */
+ public VirtualMachine getVM() {
+ if (fTarget == null) {
+ return null;
+ }
+ return fTarget.getVM();
+ }
+
+ /**
+ * Convenience method to log internal errors
+ */
+ protected void logError(Exception e) {
+ DebugJavaUtils.logError(e);
+ }
+
+ protected void run(IWorkspaceRunnable wr) throws DebugException {
+ try {
+ ResourcesPlugin.getWorkspace().run(wr, null);
+ } catch (CoreException e) {
+ throw new DebugException(e.getStatus());
+ }
+ }
+
+ /**
+ * Resets the install count attribute on the breakpoint marker
+ * to "0". Resets the expired attribute on the breakpoint marker to <code>false</code>.
+ * Resets the enabled attribute on the breakpoint marker to <code>true</code>.
+ */
+ protected void configureBreakpointAtStartup() throws CoreException {
+ List attributes= new ArrayList(3);
+ List values= new ArrayList(3);
+ if (isInstalled()) {
+ attributes.add(IJavaDebugConstants.INSTALL_COUNT);
+ values.add(new Integer(0));
+ }
+ if (isExpired()) {
+ // if breakpoint was auto-disabled, re-enable it
+ attributes.add(IJavaDebugConstants.EXPIRED);
+ values.add(Boolean.FALSE);
+ attributes.add(IDebugConstants.ENABLED);
+ values.add(Boolean.TRUE);
+ }
+ if (!attributes.isEmpty()) {
+ String[] strAttributes= new String[attributes.size()];
+ setAttributes((String[])attributes.toArray(strAttributes), values.toArray());
+ }
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpointFactory.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpointFactory.java
new file mode 100644
index 0000000..90f079c
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JavaBreakpointFactory.java
@@ -0,0 +1,37 @@
+package org.eclipse.jdt.internal.debug.core;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.IBreakpoint;
+import org.eclipse.debug.core.model.IBreakpointFactoryDelegate;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+public class JavaBreakpointFactory implements IBreakpointFactoryDelegate {
+
+ public JavaBreakpointFactory() {
+ }
+
+ public IBreakpoint createBreakpointFor(IMarker marker) throws DebugException {
+ String markerType= null;
+ try {
+ markerType= marker.getType();
+ } catch (CoreException ce) {
+ throw new DebugException(ce.getStatus());
+ }
+ if (markerType.equals(IJavaDebugConstants.JAVA_LINE_BREAKPOINT)) {
+ return new LineBreakpoint(marker);
+ } else if (markerType.equals(IJavaDebugConstants.JAVA_WATCHPOINT)) {
+ return new Watchpoint(marker);
+ } else if (markerType.equals(IJavaDebugConstants.JAVA_METHOD_ENTRY_BREAKPOINT)) {
+ return new MethodEntryBreakpoint(marker);
+ } else if (markerType.equals(IJavaDebugConstants.JAVA_RUN_TO_LINE_BREAKPOINT)) {
+ return new RunToLineBreakpoint(marker);
+ } else if (markerType.equals(IJavaDebugConstants.JAVA_EXCEPTION_BREAKPOINT)) {
+ return new ExceptionBreakpoint(marker);
+ }
+ return null;
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java
new file mode 100644
index 0000000..082bf2a
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/LineBreakpoint.java
@@ -0,0 +1,573 @@
+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.DebugException;
+import org.eclipse.debug.core.IDebugConstants;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.event.LocatableEvent;
+import com.sun.jdi.request.BreakpointRequest;
+import com.sun.jdi.request.EventRequest;
+
+public class LineBreakpoint extends JavaBreakpoint {
+
+ // Thread label String keys
+ private static final String LINE_BREAKPOINT_SYS= THREAD_LABEL + "line_breakpoint_sys";
+ private static final String LINE_BREAKPOINT_USR= THREAD_LABEL + "line_breakpoint_usr";
+ // Marker label String keys
+ private static final String LINE= "line";
+ private static final String HITCOUNT= "hitCount";
+
+ static String fMarkerType= IJavaDebugConstants.JAVA_LINE_BREAKPOINT;
+ /**
+ * Sets of attributes used to configure a line breakpoint
+ */
+ protected static final String[] fgTypeAndHitCountAttributes= new String[]{IJavaDebugConstants.TYPE_HANDLE, IJavaDebugConstants.HIT_COUNT, IJavaDebugConstants.EXPIRED};
+ protected static final String[] fgLineBreakpointAttributes= new String[]{IDebugConstants.MODEL_IDENTIFIER, IDebugConstants.ENABLED, IMarker.LINE_NUMBER, IMarker.CHAR_START, IMarker.CHAR_END};
+
+ public LineBreakpoint(){
+ }
+
+ public LineBreakpoint(IMarker marker) {
+ super(marker);
+ }
+
+ public LineBreakpoint(IType type, int lineNumber, int charStart, int charEnd, int hitCount) throws DebugException {
+ this(type, lineNumber, charStart, charEnd, hitCount, fMarkerType);
+ }
+
+ public LineBreakpoint(final IType type, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final String markerType) throws DebugException {
+ IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IResource resource= null;
+ resource= type.getUnderlyingResource();
+ if (resource == null) {
+ resource= type.getJavaProject().getProject();
+ }
+
+ // create the marker
+ fMarker= resource.createMarker(markerType);
+ setLineBreakpointAttributes(getPluginIdentifier(), true, lineNumber, charStart, charEnd);
+
+ // configure the hit count and type handle
+ setTypeAndHitCount(type, hitCount);
+
+ // configure the marker as a Java marker
+ Map attributes= getAttributes();
+ JavaCore.addJavaElementMarkerAttributes(attributes, type);
+ setAttributes(attributes);
+ }
+ };
+ run(wr);
+ }
+
+ /**
+ * @see JavaBreakpoint#installIn(JDIDebugTarget)
+ */
+ public void addToTarget(JDIDebugTarget target) {
+ String topLevelName= getTopLevelTypeName();
+ if (topLevelName == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+
+ // look for the top-level class - if it is loaded, inner classes may also be loaded
+ List classes= target.jdiClassesByName(topLevelName);
+ if (classes == null || classes.isEmpty()) {
+ // defer
+ target.defer(this, topLevelName);
+ } else {
+ // try to install
+ ReferenceType type= (ReferenceType) classes.get(0);
+ if (!installLineBreakpoint(target, type)) {
+ // install did not succeed - could be an inner type not yet loaded
+ target.defer(this, topLevelName);
+ }
+ }
+ }
+
+ /**
+ * Installs a line breakpoint in the given type, returning whether successful.
+ */
+ protected boolean installLineBreakpoint(JDIDebugTarget target, ReferenceType type) {
+ Location location= null;
+ int lineNumber= getLineNumber();
+ location= determineLocation(lineNumber, type);
+ if (location == null) {
+ // could be an inner type not yet loaded, or line information not available
+ return false;
+ }
+
+ if (createLineBreakpointRequest(location, target) != null) {
+ // update the install attibute on the breakpoint
+ if (!target.inHCR()) {
+ try {
+ incrementInstallCount();
+ } catch (CoreException e) {
+ logError(e);
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+
+ }
+
+ /**
+ * Creates, installs, and returns a line breakpoint request at
+ * the given location for the given breakpoint.
+ */
+ protected BreakpointRequest createLineBreakpointRequest(Location location, JDIDebugTarget target) {
+ BreakpointRequest request = null;
+ try {
+ request= target.getEventRequestManager().createBreakpointRequest(location);
+ configureRequest(request);
+ } catch (VMDisconnectedException e) {
+ target.uninstallBreakpoint(this);
+ return null;
+ } catch (RuntimeException e) {
+ target.uninstallBreakpoint(this);
+ logError(e);
+ return null;
+ }
+ request.setEnabled(isEnabled());
+ target.installBreakpoint(this, request);
+ return request;
+ }
+
+
+ /**
+ * Returns a location for the line number in the given type, or any of its
+ * nested types. Returns <code>null</code> if a location cannot be determined.
+ */
+ protected Location determineLocation(int lineNumber, ReferenceType type) {
+ List locations= null;
+ try {
+ locations= type.locationsOfLine(lineNumber);
+ } catch (AbsentInformationException e) {
+ return null;
+ } catch (NativeMethodException e) {
+ return null;
+ } catch (InvalidLineNumberException e) {
+ //possible in a nested type, fall through and traverse nested types
+ } catch (VMDisconnectedException e) {
+ return null;
+ } catch (ClassNotPreparedException e) {
+ // could be a nested type that is not yet loaded
+ return null;
+ } catch (RuntimeException e) {
+ // not able to retrieve line info
+ logError(e);
+ return null;
+ }
+
+ if (locations != null && locations.size() > 0) {
+ return (Location) locations.get(0);
+ } else {
+ Iterator nestedTypes= null;
+ try {
+ nestedTypes= type.nestedTypes().iterator();
+ } catch (RuntimeException e) {
+ // not able to retrieve line info
+ logError(e);
+ return null;
+ }
+ while (nestedTypes.hasNext()) {
+ ReferenceType nestedType= (ReferenceType) nestedTypes.next();
+ Location innerLocation= determineLocation(lineNumber, nestedType);
+ if (innerLocation != null) {
+ return innerLocation;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public void changeForTarget(JDIDebugTarget target) {
+ BreakpointRequest request= (BreakpointRequest) target.getRequest(this);
+ if (request != null) {
+ // already installed - could be a change in the enabled state or hit count
+ //may result in a new request being generated
+ request= updateHitCount(request, target);
+ if (request != null) {
+ updateEnabledState(request);
+ target.installBreakpoint(this, request);
+ }
+ }
+ }
+
+ /**
+ * Update the hit count of an <code>EventRequest</code>. Return a new request with
+ * the appropriate settings.
+ */
+ protected BreakpointRequest updateHitCount(BreakpointRequest request, JDIDebugTarget target) {
+
+ // if the hit count has changed, or the request has expired and is being re-enabled,
+ // create a new request
+ if (hasHitCountChanged(request) || (isExpired(request) && this.isEnabled())) {
+ try {
+ // delete old request
+ //on JDK you cannot delete (disable) an event request that has hit its count filter
+ if (!isExpired(request)) {
+ target.getEventRequestManager().deleteEventRequest(request); // disable & remove
+ }
+ Location location = ((BreakpointRequest) request).location();
+ request = createLineBreakpointRequest(location, target);
+ } catch (VMDisconnectedException e) {
+ } catch (RuntimeException e) {
+ logError(e);
+ }
+ }
+ return request;
+ }
+
+ /**
+ * Returns whether the hitCount of this breakpoint is equal to the hitCount of
+ * the associated request.
+ */
+ protected boolean hasHitCountChanged(EventRequest request) {
+ int hitCount= getHitCount();
+ Integer requestCount= (Integer) request.getProperty(IJavaDebugConstants.HIT_COUNT);
+ int oldCount = -1;
+ if (requestCount != null) {
+ oldCount = requestCount.intValue();
+ }
+ return hitCount != oldCount;
+ }
+
+
+ /**
+ * Configure a breakpoint request with common properties:
+ * <ul>
+ * <li><code>IDebugConstants.BREAKPOINT_MARKER</code></li>
+ * <li><code>IJavaDebugConstants.HIT_COUNT</code></li>
+ * <li><code>IJavaDebugConstants.EXPIRED</code></li>
+ * </ul>
+ * and sets the suspend policy of the request to suspend the event thread.
+ */
+ protected void configureRequest(EventRequest request) {
+ request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
+ request.putProperty(IDebugConstants.BREAKPOINT, this);
+ int hitCount= getHitCount();
+ if (hitCount > 0) {
+ request.addCountFilter(hitCount);
+ request.putProperty(IJavaDebugConstants.HIT_COUNT, new Integer(hitCount));
+ request.putProperty(IJavaDebugConstants.EXPIRED, Boolean.FALSE);
+ }
+ }
+
+ /**
+ * Enable a request and increment the install count of the associated breakpoint.
+ */
+ protected void completeConfiguration(EventRequest request) {
+ // Important: Enable only after request has been configured
+ try {
+ request.setEnabled(isEnabled());
+ incrementInstallCount();
+ } catch (CoreException e) {
+ logError(e);
+ }
+ }
+
+ /**
+ * @see JavaBreakpoint#handleEvent(Event)
+ */
+ public void handleEvent(Event event, JDIDebugTarget target) {
+ if (!(event instanceof LocatableEvent)) {
+ return;
+ }
+ ThreadReference threadRef= ((LocatableEvent)event).thread();
+ JDIThread thread= target.findThread(threadRef);
+ if (thread == null) {
+ target.resume(threadRef);
+ return;
+ } else {
+ thread.handleSuspendForBreakpoint(this);
+ expireHitCount((LocatableEvent)event);
+ }
+ }
+
+ /**
+ * Called when a breakpoint event is encountered
+ */
+ public void expireHitCount(LocatableEvent event) {
+ EventRequest request= (EventRequest)event.request();
+ Integer requestCount= (Integer) request.getProperty(IJavaDebugConstants.HIT_COUNT);
+ if (requestCount != null) {
+ try {
+ request.putProperty(IJavaDebugConstants.EXPIRED, Boolean.TRUE);
+ this.disable();
+ // make a note that we auto-disabled this breakpoint.
+ setExpired(true);
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+ }
+
+ /**
+ * @see JavaBreakpoint#removeFromTarget(JDIDebugTarget)
+ */
+ public void removeFromTarget(JDIDebugTarget target) {
+ BreakpointRequest request= (BreakpointRequest) target.getRequest(this);
+ if (request == null) {
+ //deferred breakpoint
+ if (!this.exists()) {
+ //resource no longer exists
+ return;
+ }
+ String name= getTopLevelTypeName();
+ if (name == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+ List breakpoints= (List) target.getDeferredBreakpointsByClass(name);
+ if (breakpoints == null) {
+ return;
+ }
+
+ breakpoints.remove(this);
+ if (breakpoints.isEmpty()) {
+ target.removeDeferredBreakpointByClass(name);
+ }
+ } else {
+ //installed breakpoint
+ try {
+ // cannot delete an expired request
+ if (!isExpired(request)) {
+ target.getEventRequestManager().deleteEventRequest(request); // disable & remove
+ }
+ } catch (VMDisconnectedException e) {
+ return;
+ } catch (RuntimeException e) {
+ logError(e);
+ }
+ }
+ }
+
+ /**
+ * Returns the <code>HIT_COUNT</code> attribute of the given breakpoint
+ * or -1 if the attribute is not set.
+ */
+ public int getHitCount() {
+ return getAttribute(IJavaDebugConstants.HIT_COUNT, -1);
+ }
+
+ /**
+ * Sets the <code>HIT_COUNT</code> attribute of the given breakpoint,
+ * and resets the <code>EXPIRED</code> attribute to false (since, if
+ * the hit count is changed, the breakpoint should no longer be expired).
+ */
+ public void setHitCount(int count) throws CoreException {
+ setAttributes(new String[]{IJavaDebugConstants.HIT_COUNT, IJavaDebugConstants.EXPIRED},
+ new Object[]{new Integer(count), Boolean.FALSE});
+ }
+
+ /**
+ * @see JavaBreakpoint#isSupportedBy(VirtualMachine)
+ */
+ public boolean isSupportedBy(VirtualMachine vm) {
+ return true;
+ }
+
+ /**
+ * Returns whether the given breakpoint has expired.
+ */
+ public boolean isExpired() {
+ return getBooleanAttribute( IJavaDebugConstants.EXPIRED);
+ }
+
+ /**
+ * Sets the <code>EXPIRED</code> attribute of the given breakpoint.
+ */
+ public void setExpired(boolean expired) throws CoreException {
+ setBooleanAttribute(IJavaDebugConstants.EXPIRED, expired);
+ }
+
+ /**
+ * Returns the method the given breakpoint is installed in
+ * or <code>null</code> if a method cannot be resolved.
+ */
+ public IMethod getMethod() {
+ try {
+ String handle = getMethodHandleIdentifier();
+ if (handle != null) {
+ return (IMethod)JavaCore.create(handle);
+ }
+ } catch (CoreException e) {
+ logError(e);
+ }
+ return null;
+ }
+
+ /**
+ * Set standard attributes of a line breakpoint
+ */
+ public void setLineBreakpointAttributes(String modelIdentifier, boolean enabled, int lineNumber, int charStart, int charEnd) throws CoreException {
+ Object[] values= new Object[]{getPluginIdentifier(), new Boolean(true), new Integer(lineNumber), new Integer(charStart), new Integer(charEnd)};
+ setAttributes(fgLineBreakpointAttributes, values);
+ }
+
+ /**
+ * Sets the <code>TYPE_HANDLE</code> attribute of the given breakpoint, associated
+ * with the given IType.
+ *
+ * If <code>hitCount > 0</code>, sets the <code>HIT_COUNT</code> attribute of the given breakpoint,
+ * and resets the <code>EXPIRED</code> attribute to false (since, if
+ * the hit count is changed, the breakpoint should no longer be expired).
+ */
+ public void setTypeAndHitCount(IType type, int hitCount) throws CoreException {
+ if (hitCount == 0) {
+ setType(type);
+ return;
+ }
+ String handle = type.getHandleIdentifier();
+ Object[] values= new Object[]{handle, new Integer(hitCount), Boolean.FALSE};
+ setAttributes(fgTypeAndHitCountAttributes, values);
+ }
+
+ /**
+ * Returns the <code>METHOD_HANDLE</code> attribute of the given breakpoint.
+ */
+ public String getMethodHandleIdentifier() throws CoreException {
+ return (String)getAttribute(IJavaDebugConstants.METHOD_HANDLE);
+ }
+
+ /**
+ * Returns the smallest determinable <code>IMember</code> the given breakpoint is installed in.
+ */
+ public IMember getMember() {
+ int start = getCharStart();
+ int end = getCharEnd();
+ IType type = getBreakpointType();
+ IMember member = null;
+ if (type != null && end >= start && start >= 0) {
+ try {
+ if (type.isBinary()) {
+ member= binSearch(type.getClassFile(), type, start, end);
+ } else {
+ member= binSearch(type.getCompilationUnit(), type, start, end);
+ }
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+ if (member == null) {
+ member= type;
+ }
+ return member;
+ }
+
+ /**
+ * Searches the given source range of the container for a member that is
+ * not the same as the given type.
+ */
+ protected IMember binSearch(IClassFile container, IType type, int start, int end) throws JavaModelException {
+ IJavaElement je = container.getElementAt(start);
+ if (je != null && !je.equals(type)) {
+ return (IMember)je;
+ }
+ if (end > start) {
+ je = container.getElementAt(end);
+ if (je != null && !je.equals(type)) {
+ return (IMember)je;
+ }
+ int mid = ((end - start) / 2) + start;
+ if (mid > start) {
+ je = binSearch(container, type, start + 1, mid);
+ if (je == null) {
+ je = binSearch(container, type, mid + 1, end - 1);
+ }
+ return (IMember)je;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Searches the given source range of the container for a member that is
+ * not the same as the given type.
+ */
+ protected IMember binSearch(ICompilationUnit container, IType type, int start, int end) throws JavaModelException {
+ IJavaElement je = container.getElementAt(start);
+ if (je != null && !je.equals(type)) {
+ return (IMember)je;
+ }
+ if (end > start) {
+ je = container.getElementAt(end);
+ if (je != null && !je.equals(type)) {
+ return (IMember)je;
+ }
+ int mid = ((end - start) / 2) + start;
+ if (mid > start) {
+ je = binSearch(container, type, start + 1, mid);
+ if (je == null) {
+ je = binSearch(container, type, mid + 1, end - 1);
+ }
+ return (IMember)je;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @see JavaBreakpoint
+ */
+ public String getFormattedThreadText(String threadName, String typeName, boolean systemThread) {
+ int lineNumber= getAttribute(IMarker.LINE_NUMBER, -1);
+ if (lineNumber > -1) {
+ if (systemThread) {
+ return getFormattedString(LINE_BREAKPOINT_SYS, new String[] {threadName, String.valueOf(lineNumber), typeName});
+ } else {
+ return getFormattedString(LINE_BREAKPOINT_USR, new String[] {threadName, String.valueOf(lineNumber), typeName});
+ }
+ }
+ return "";
+ }
+
+ public String getMarkerText(boolean showQualified, String memberString) {
+ IType type= getBreakpointType();
+ if (type != null) {
+ StringBuffer label= new StringBuffer();
+ if (showQualified) {
+ label.append(type.getFullyQualifiedName());
+ } else {
+ label.append(type.getElementName());
+ }
+ int lineNumber= getLineNumber();
+ if (lineNumber > 0) {
+ label.append(" [");
+ label.append(DebugJavaUtils.getResourceString(MARKER_LABEL + LINE));
+ label.append(' ');
+ label.append(lineNumber);
+ label.append(']');
+
+ }
+ int hitCount= getHitCount();
+ if (hitCount > 0) {
+ label.append(" [");
+ label.append(DebugJavaUtils.getResourceString(MARKER_LABEL + HITCOUNT));
+ label.append(' ');
+ label.append(hitCount);
+ label.append(']');
+ }
+ if (memberString != null) {
+ label.append(" - ");
+ label.append(memberString);
+ }
+ return label.toString();
+ }
+ return "";
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java
new file mode 100644
index 0000000..838dadc
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/MethodEntryBreakpoint.java
@@ -0,0 +1,231 @@
+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);
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/RunToLineBreakpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/RunToLineBreakpoint.java
new file mode 100644
index 0000000..0d505e8
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/RunToLineBreakpoint.java
@@ -0,0 +1,61 @@
+package org.eclipse.jdt.internal.debug.core;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+public class RunToLineBreakpoint extends LineBreakpoint {
+
+ // Thread label String keys
+ private static final String RUN_TO_LINE_SYS= THREAD_LABEL + "run_to_line_sys";
+ private static final String RUN_TO_LINE_USR= THREAD_LABEL + "run_to_line_usr";
+
+ static String fMarkerType= IJavaDebugConstants.JAVA_RUN_TO_LINE_BREAKPOINT;
+
+ /**
+ * Create a run to line breakpoint on the given marker
+ */
+ public RunToLineBreakpoint(IMarker marker) {
+ fMarker= marker;
+ }
+
+ /**
+ * Creates a run-to-line breakpoint in the
+ * given type, at the given line number. If a character range within the
+ * line is known, it may be specified by charStart/charEnd. Run-to-line
+ * breakpoints have a hit count of 1.
+ *
+ * @param type the type in which to create the breakpoint
+ * @param lineNumber the lineNumber on which the breakpoint is created - line
+ * numbers are 1 based, associated with the compilation unit in which
+ * the type is defined
+ * @param charStart the first character index associated with the breakpoint,
+ * or -1 if unspecified
+ * @param charEnd the last character index associated with the breakpoint,
+ * or -1 if unspecified
+ * @return a run-to-line breakpoint
+ * @exception DebugException if unable to create the breakpoint marker due
+ * to a lower level exception.
+ */
+ public RunToLineBreakpoint(IType type, int lineNumber, int charStart, int charEnd) throws DebugException {
+ super(type, lineNumber, charStart, charEnd, 1, fMarkerType);
+ }
+
+ /**
+ * @see JavaBreakpoint
+ */
+ public String getFormattedThreadText(String threadName, String typeName, boolean systemThread) {
+ int lineNumber= getAttribute(IMarker.LINE_NUMBER, -1);
+ if (lineNumber > -1) {
+ if (systemThread) {
+ return getFormattedString(RUN_TO_LINE_SYS, new String[] {threadName, String.valueOf(lineNumber), typeName});
+ } else {
+ return getFormattedString(RUN_TO_LINE_USR, new String[] {threadName, String.valueOf(lineNumber), typeName});
+ }
+ }
+ return "";
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/Watchpoint.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/Watchpoint.java
new file mode 100644
index 0000000..8b0a9ca
--- /dev/null
+++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/Watchpoint.java
@@ -0,0 +1,674 @@
+package org.eclipse.jdt.internal.debug.core;
+
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.jdt.core.*;
+import org.eclipse.jdt.debug.core.IJavaDebugConstants;
+
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+public class Watchpoint extends LineBreakpoint {
+
+ // Thread label String keys
+ private static final String ACCESS_SYS= THREAD_LABEL + "access_sys";
+ private static final String ACCESS_USR= THREAD_LABEL + "access_usr";
+ private static final String MODIFICATION_SYS= THREAD_LABEL + "modification_sys";
+ private static final String MODIFICATION_USR= THREAD_LABEL + "modification_usr";
+ // Error String keys
+ private final static String PREFIX= "jdi_breakpoint.";
+ private final static String ERROR = PREFIX + "error.";
+ private final static String ERROR_ACCESS_WATCHPOINT_NOT_SUPPORTED = ERROR + "access.not_supported";
+ private final static String ERROR_MODIFICATION_WATCHPOINT_NOT_SUPPORTED = ERROR + "modification.net_supported";
+ // Marker label String keys
+ protected final static String WATCHPOINT= MARKER_LABEL + "watchpoint.";
+ protected final static String FORMAT= WATCHPOINT + "format";
+ protected final static String ACCESS= WATCHPOINT + "access";
+ protected final static String MODIFICATION= WATCHPOINT + "modification";
+ protected final static String BOTH= WATCHPOINT + "both";
+
+ static String fMarkerType= IJavaDebugConstants.JAVA_WATCHPOINT;
+
+ private final static int ACCESS_EVENT= 0;
+ private final static int MODIFICATION_EVENT= 1;
+ private int fLastEventType= -1;
+
+ /**
+ * Create a watchpoint for the given marker
+ */
+ public Watchpoint(IMarker marker) {
+ super(marker);
+ }
+
+ /**
+ * Creates and returns a watchpoint on the
+ * given field.
+ * If hitCount > 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 field the field on which to suspend (on access or modification)
+ * @param hitCount the number of times the breakpoint will be hit before
+ * suspending execution - 0 if it should always suspend
+ * @return a watchpoint
+ * @exception DebugException if unable to create the breakpoint marker due
+ * to a lower level exception
+ */
+ public Watchpoint(final IField field) throws DebugException {
+ IWorkspaceRunnable wr= new IWorkspaceRunnable() {
+ public void run(IProgressMonitor monitor) throws CoreException {
+ IResource resource = null;
+ ICompilationUnit compilationUnit = getCompilationUnit(field);
+ if (compilationUnit != null) {
+ resource = compilationUnit.getUnderlyingResource();
+ }
+ if (resource == null) {
+ resource = field.getJavaProject().getProject();
+ }
+
+ if (fMarker == null) {
+ // Only create a marker if one is not already assigned
+ fMarker= resource.createMarker(fMarkerType);
+ }
+
+ // configure the standard attributes
+ setStandardAttributes(field);
+ // configure the type handle and hit count
+ setTypeAndHitCount(field.getDeclaringType(), 0);
+ // configure the field handle
+ setField(field);
+ // configure the access and modification flags to defaults
+ setDefaultAccessAndModification();
+ setAutoDisabled(false);
+
+
+ // configure the marker as a Java marker
+ Map attributes= getAttributes();
+ JavaCore.addJavaElementMarkerAttributes(attributes, field);
+ setAttributes(attributes);
+ }
+ };
+ run(wr);
+ }
+
+ /**
+ * @see JavaBreakpoint#installIn(JDIDebugTarget)
+ */
+ public void addToTarget(JDIDebugTarget target) {
+ selectiveAdd(target, true, true);
+ }
+
+ /**
+ * A single watchpoint can create multiple requests. This method provides control over this
+ * property for explicitly choosing which requests (access, modification, or both) to
+ * potentially add.
+ */
+ protected void selectiveAdd(JDIDebugTarget target, boolean accessCheck, boolean modificationCheck) {
+ fTarget= target;
+ String topLevelName= getTopLevelTypeName();
+ if (topLevelName == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+
+ List classes= target.jdiClassesByName(topLevelName);
+ if (classes == null || classes.isEmpty()) {
+ // defer
+ target.defer(this, topLevelName);
+ return;
+ }
+
+ IField javaField= getField();
+ Field field= null;
+ ReferenceType reference= null;
+ for (int i=0; i<classes.size(); i++) {
+ reference= (ReferenceType) classes.get(i);
+ field= reference.fieldByName(javaField.getElementName());
+ if (field == null) {
+ return;
+ }
+ AccessWatchpointRequest accessRequest= null;
+ ModificationWatchpointRequest modificationRequest= null;
+ // If we're not supposed to check access or modification, just retrieve the
+ // existing request
+ if (!accessCheck) {
+ accessRequest= target.getAccessWatchpointRequest(field);
+ }
+ if (!modificationCheck) {
+ modificationRequest= target.getModificationWatchpointRequest(field);
+ }
+ if (isAccess() && accessCheck) {
+ if (accessSupportedBy(target.getVM())) {
+ accessRequest= accessWatchpointAdded(target, field);
+ } else {
+ notSupported(ERROR_ACCESS_WATCHPOINT_NOT_SUPPORTED);
+ }
+ }
+ if (isModification() && modificationCheck) {
+ if (modificationSupportedBy(target.getVM())) {
+ modificationRequest= modificationWatchpointAdded(target, field);
+ } else {
+ notSupported(ERROR_MODIFICATION_WATCHPOINT_NOT_SUPPORTED);
+ }
+ }
+ if (!(accessRequest == null && modificationRequest == null)) {
+ Object[] requests= {accessRequest, modificationRequest};
+ target.installBreakpoint(this, requests);
+ try {
+ incrementInstallCount();
+ } catch (CoreException e) {
+ target.internalError(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns whether this kind of breakpoint is supported by the given
+ * virtual machine. A watchpoint is supported if both access and
+ * modification watchpoints are supported.
+ */
+ public boolean isSupportedBy(VirtualMachine vm) {
+ return (modificationSupportedBy(vm) && accessSupportedBy(vm));
+ }
+
+ /**
+ * Returns whether the given virtual machine supports modification watchpoints
+ */
+ public boolean modificationSupportedBy(VirtualMachine vm) {
+ return vm.canWatchFieldModification();
+ }
+
+ /**
+ * Returns whether the given virtual machine supports access watchpoints
+ */
+ public boolean accessSupportedBy(VirtualMachine vm) {
+ return vm.canWatchFieldAccess();
+ }
+
+ /**
+ * This watchpoint is not supported for some reason. Alert the user.
+ */
+ protected void notSupported(String error_key) {
+ }
+
+ /**
+ * An access watchpoint has been added.
+ * Create or update the request.
+ */
+ protected AccessWatchpointRequest accessWatchpointAdded(JDIDebugTarget target, Field field) {
+ AccessWatchpointRequest request= target.getAccessWatchpointRequest(field);
+ if (request == null) {
+ request= createAccessWatchpoint(target, field);
+ }
+ // Important: Enable only after request has been configured
+ request.setEnabled(isEnabled());
+ return request;
+ }
+
+ /**
+ * Create an access watchpoint for the given breakpoint and associated field
+ */
+ protected AccessWatchpointRequest createAccessWatchpoint(JDIDebugTarget target, Field field) {
+ AccessWatchpointRequest request= null;
+ try {
+ request= target.getEventRequestManager().createAccessWatchpointRequest(field);
+ configureRequest(request);
+ } catch (VMDisconnectedException e) {
+ return null;
+ } catch (RuntimeException e) {
+ target.internalError(e);
+ return null;
+ }
+ return request;
+ }
+
+ /**
+ * A modification watchpoint has been added.
+ * Create or update the request.
+ */
+ protected ModificationWatchpointRequest modificationWatchpointAdded(JDIDebugTarget target, Field field) {
+ ModificationWatchpointRequest request= target.getModificationWatchpointRequest(field);
+ if (request == null) {
+ request= createModificationWatchpoint(target, field);
+ }
+ // Important: only enable a request after it has been configured
+ request.setEnabled(isEnabled());
+ return request;
+ }
+
+ /**
+ * Create a modification watchpoint for the given breakpoint and associated field
+ */
+ protected ModificationWatchpointRequest createModificationWatchpoint(JDIDebugTarget target, Field field) {
+ ModificationWatchpointRequest request= null;
+ try {
+ request= target.getEventRequestManager().createModificationWatchpointRequest(field);
+ configureRequest(request);
+ } catch (VMDisconnectedException e) {
+ return null;
+ } catch (RuntimeException e) {
+ target.internalError(e);
+ return null;
+ }
+ return request;
+ }
+
+ /**
+ * A watchpoint has been changed.
+ * Update the request.
+ */
+ public void changeForTarget(JDIDebugTarget target) {
+ Object[] requests= (Object[])target.getRequest(this);
+ for (int i=0; i < requests.length; i++) {
+ WatchpointRequest request= (WatchpointRequest)requests[i];
+ if (request == null) {
+ if ((i == 0) && isAccess()) {
+ selectiveAdd(target, true, false);
+ }
+ if ((i == 1) && isModification()) {
+ selectiveAdd(target, false, true);
+ }
+ continue;
+ }
+ if ((!isAccess() && (request instanceof AccessWatchpointRequest)) ||
+ (!isModification() && (request instanceof ModificationWatchpointRequest))) {
+ target.getEventRequestManager().deleteEventRequest(request); // disable & remove
+ continue;
+ }
+ request= (WatchpointRequest)updateHitCount(request, target);
+
+ if (request != null) {
+ updateEnabledState(request);
+ requests[i]= request;
+ }
+ }
+ }
+
+ /**
+ * Update the hit count of an <code>EventRequest</code>. Return a new request with
+ * the appropriate settings.
+ */
+ protected EventRequest updateHitCount(EventRequest request, JDIDebugTarget target) {
+
+ // if the hit count has changed, or the request has expired and is being re-enabled,
+ // create a new request
+ if (hasHitCountChanged(request) || (isExpired(request) && this.isEnabled())) {
+ try {
+ // delete old request
+ //on JDK you cannot delete (disable) an event request that has hit its count filter
+ if (!isExpired(request)) {
+ target.getEventRequestManager().deleteEventRequest(request); // disable & remove
+ }
+ Field field= ((WatchpointRequest) request).field();
+ if (request instanceof AccessWatchpointRequest) {
+ request= createAccessWatchpoint(target, field);
+ } else if (request instanceof ModificationWatchpointRequest) {
+ request= createModificationWatchpoint(target, field);
+ }
+ } catch (VMDisconnectedException e) {
+ } catch (RuntimeException e) {
+ logError(e);
+ }
+ }
+ return request;
+ }
+
+ /**
+ * @see JavaBreakpoint#removeFromTarget(JDIDebugTarget)
+ */
+ public void removeFromTarget(JDIDebugTarget target) {
+ Object[] requests= (Object[]) target.getRequest(this);
+ if (requests == null) {
+ //deferred breakpoint
+ if (!this.exists()) {
+ //resource no longer exists
+ return;
+ }
+ String name= getTopLevelTypeName();
+ if (name == null) {
+// internalError(ERROR_BREAKPOINT_NO_TYPE);
+ return;
+ }
+ List breakpoints= (List) target.getDeferredBreakpointsByClass(name);
+ if (breakpoints == null) {
+ return;
+ }
+
+ breakpoints.remove(this);
+ if (breakpoints.isEmpty()) {
+ target.removeDeferredBreakpointByClass(name);
+ }
+ } else {
+ //installed breakpoint
+ try {
+ for (int i=0; i<requests.length; i++) {
+ WatchpointRequest request= (WatchpointRequest)requests[i];
+ if (request == null) {
+ continue;
+ }
+ target.getEventRequestManager().deleteEventRequest(request); // disable & remove
+ }
+ try {
+ decrementInstallCount();
+ } catch (CoreException e) {
+ fTarget= null;
+ logError(e);
+ }
+ } catch (VMDisconnectedException e) {
+ fTarget= null;
+ return;
+ } catch (RuntimeException e) {
+ fTarget= null;
+ logError(e);
+ }
+ }
+ fTarget= null;
+ }
+
+ /**
+ * Enable this watchpoint.
+ *
+ * If the watchpoint is not watching access or modification,
+ * set the default values. If this isn't done, the resulting
+ * state (enabled with access and modification both disabled)
+ * is ambiguous.
+ */
+ public void enable() {
+ if (!(isAccess() || isModification())) {
+ setDefaultAccessAndModification();
+ }
+ super.enable();
+ }
+
+ /**
+ * Returns whether this watchpoint is an access watchpoint
+ */
+ public boolean isAccess() {
+ return getAttribute(IJavaDebugConstants.ACCESS, false);
+ }
+
+ /**
+ * Toggle the access attribute of this watchpoint
+ */
+ public void toggleAccess() {
+ setAccess(!isAccess());
+ }
+
+ /**
+ * Sets the access attribute of this watchpoint. If access is set to true
+ * and the watchpoint is disabled, enable the watchpoint. If both access and
+ * modification are false, disable the watchpoint.
+ */
+ public void setAccess(boolean access) {
+ if (access == isAccess()) {
+ return;
+ }
+ try {
+ setAttribute(IJavaDebugConstants.ACCESS, access);
+ if (access && !isEnabled()) {
+ enable();
+ } else if (!(access || isModification())) {
+ disable();
+ }
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ if (fTarget != null) {
+ // Notify the target that this watchpoint has changed
+ changeForTarget(fTarget);
+ }
+ }
+
+ /**
+ * Returns whether this watchpoint is a modification watchpoint
+ */
+ public boolean isModification() {
+ return getAttribute(IJavaDebugConstants.MODIFICATION, false);
+ }
+
+ /**
+ * Toggle the modification attribute of this watchpoint
+ */
+ public void toggleModification() {
+ setModification(!isModification());
+ }
+
+ /**
+ * Sets the modification attribute of this watchpoint. If modification is set to true
+ * and the watchpoint is disabled, enable the watchpoint. If both access and
+ * modification are false, disable the watchpoint.
+ */
+ public void setModification(boolean modification) {
+ if (modification == isModification()) {
+ return;
+ }
+ try {
+ setAttribute(IJavaDebugConstants.MODIFICATION, modification);
+ if (modification && !isEnabled()) {
+ enable();
+ } else if (!(modification || isAccess())) {
+ disable();
+ }
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ if (fTarget != null) {
+ // Notify the target that this watchpoint has changed
+ changeForTarget(fTarget);
+ }
+ }
+
+ /**
+ * Sets the default access and modification attributes of the watchpoint.
+ * The default values are:
+ * <ul>
+ * <li>access = <code>false</code>
+ * <li>modification = <code>true</code>
+ * <ul>
+ */
+ public void setDefaultAccessAndModification() {
+ Object[] values= new Object[]{Boolean.FALSE, Boolean.TRUE};
+ String[] attributes= new String[]{IJavaDebugConstants.ACCESS, IJavaDebugConstants.MODIFICATION};
+ try {
+ setAttributes(attributes, values);
+ } catch (CoreException ce) {
+ logError(ce);
+ }
+ }
+
+ /**
+ * Sets the <code>FIELD_HANDLE</code> attribute of the given breakpoint, associated
+ * with the given IField.
+ */
+ public void setField(IField field) throws CoreException {
+ String handle = field.getHandleIdentifier();
+ setFieldHandleIdentifier(handle);
+ }
+
+ /**
+ * Sets the <code>FIELD_HANDLE</code> attribute of the given breakpoint.
+ */
+ public void setFieldHandleIdentifier(String handle) throws CoreException {
+ setAttribute(IJavaDebugConstants.FIELD_HANDLE, handle);
+ }
+
+ /**
+ * Set standard attributes of a watchpoint
+ */
+ public void setStandardAttributes(IField field) throws CoreException {
+ // find the source range if available
+ int start = -1;
+ int stop = -1;
+ ISourceRange range = field.getSourceRange();
+ if (range != null) {
+ start = range.getOffset();
+ stop = start + range.getLength() - 1;
+ }
+ super.setLineBreakpointAttributes(getPluginIdentifier(), true, -1, start, stop);
+ }
+
+ /**
+ * Sets the <code>AUTO_DISABLED</code> attribute of the given breakpoint.
+ */
+ public void setAutoDisabled(boolean autoDisabled) throws CoreException {
+ setAttribute(IJavaDebugConstants.AUTO_DISABLED, autoDisabled);
+ }
+
+ /**
+ * Returns the underlying compilation unit of an element.
+ */
+ public static ICompilationUnit getCompilationUnit(IJavaElement element) {
+ if (element instanceof IWorkingCopy) {
+ return (ICompilationUnit) ((IWorkingCopy) element).getOriginalElement();
+ }
+ if (element instanceof ICompilationUnit) {
+ return (ICompilationUnit) element;
+ }
+ IJavaElement parent = element.getParent();
+ if (parent != null) {
+ return getCompilationUnit(parent);
+ }
+ return null;
+ }
+
+ /**
+ * Generate the field associated with the given marker
+ */
+ public IField getField(IMarker marker) {
+ String handle= getFieldHandleIdentifier(marker);
+ if (handle != null && handle != "") {
+ return (IField)JavaCore.create(handle);
+ }
+ return null;
+ }
+
+ /**
+ * Generate the field associated with this watchpoint
+ */
+ public IField getField() {
+ String handle= getFieldHandleIdentifier();
+ if (handle != null && handle != "") {
+ return (IField)JavaCore.create(handle);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the <code>FIELD_HANDLE</code> attribute of the given marker.
+ */
+ public String getFieldHandleIdentifier(IMarker marker) {
+ String handle;
+ try {
+ handle= (String)marker.getAttribute(IJavaDebugConstants.FIELD_HANDLE);
+ } catch (CoreException ce) {
+ handle= "";
+ logError(ce);
+ }
+ return handle;
+ }
+
+ /**
+ * Returns the <code>FIELD_HANDLE</code> attribute of this watchpoint.
+ */
+ public String getFieldHandleIdentifier() {
+ String handle;
+ try {
+ handle= (String)getAttribute(IJavaDebugConstants.FIELD_HANDLE);
+ } catch (CoreException ce) {
+ handle= "";
+ logError(ce);
+ }
+ return handle;
+ }
+
+ /**
+ * @see JavaBreakpoint
+ */
+ public String getFormattedThreadText(String threadName, String typeName, boolean systemThread) {
+ String fieldName= getField().getElementName();
+ if (fLastEventType == ACCESS_EVENT) {
+ if (systemThread) {
+ return getFormattedString(ACCESS_SYS, new String[] {threadName, fieldName, typeName});
+ } else {
+ return getFormattedString(ACCESS_USR, new String[] {threadName, fieldName, typeName});
+ }
+ } else if (fLastEventType == MODIFICATION_EVENT) {
+ // modification
+ if (systemThread) {
+ return getFormattedString(MODIFICATION_SYS, new String[] {threadName, fieldName, typeName});
+ } else {
+ return getFormattedString(MODIFICATION_USR, new String[] {threadName, fieldName, typeName});
+ }
+ }
+ return "";
+ }
+
+ public String getMarkerText(boolean qualified, String memberString) {
+ String lineInfo= super.getMarkerText(qualified, memberString);
+
+ String state= null;
+ boolean access= isAccess();
+ boolean modification= isModification();
+ if (access && modification) {
+ state= BOTH;
+ } else if (access) {
+ state= ACCESS;
+ } else if (modification) {
+ state= MODIFICATION;
+ }
+ String label= null;
+ if (state == null) {
+ label= lineInfo;
+ } else {
+ String format= DebugJavaUtils.getResourceString(FORMAT);
+ state= DebugJavaUtils.getResourceString(state);
+ label= MessageFormat.format(format, new Object[] {state, lineInfo});
+ }
+ return label;
+ }
+
+ /**
+ * Store the type of the event, then handle it as specified in
+ * the superclass. This is useful for correctly generating the
+ * thread text when asked (assumes thread text is requested after
+ * the event is passed to this breakpoint.
+ *
+ * Also, @see JavaBreakpoint#handleEvent(Event)
+ */
+ public void handleEvent(Event event, JDIDebugTarget target) {
+ if (event instanceof AccessWatchpointEvent) {
+ fLastEventType= ACCESS_EVENT;
+ } else if (event instanceof ModificationWatchpointEvent) {
+ fLastEventType= MODIFICATION_EVENT;
+ }
+ super.handleEvent(event, target);
+ }
+
+ /**
+ * Returns the <code>HIT_COUNT</code> attribute of the given breakpoint
+ * or -1 if the attribute is not set.
+ */
+ public int getHitCount() {
+ return getAttribute(IJavaDebugConstants.HIT_COUNT, -1);
+ }
+
+ /**
+ * Sets the <code>HIT_COUNT</code> attribute of the given breakpoint,
+ * and resets the <code>EXPIRED</code> attribute to false (since, if
+ * the hit count is changed, the breakpoint should no longer be expired).
+ */
+ public void setHitCount(int count) throws CoreException {
+ setAttributes(new String[]{IJavaDebugConstants.HIT_COUNT, IJavaDebugConstants.EXPIRED},
+ new Object[]{new Integer(count), Boolean.FALSE});
+ }
+
+}
+
diff --git a/org.eclipse.jdt.debug/plugin.xml b/org.eclipse.jdt.debug/plugin.xml
index d6cc702..fc7a07b 100644
--- a/org.eclipse.jdt.debug/plugin.xml
+++ b/org.eclipse.jdt.debug/plugin.xml
@@ -27,17 +27,30 @@
<!-- Extensions -->
<!-- Extension points -->
<extension
- id="javaLineBreakpoint"
- point="org.eclipse.core.resources.markers">
- <super
- type="org.eclipse.debug.core.lineBreakpoint">
- </super>
+ id="javaBreakpoint"
+ point="org.eclipse.core.resources.markers">
+ <super
+ type="org.eclipse.debug.core.breakpoint">
+ </super>
<persistent
value="true">
</persistent>
<attribute
name="typeHandle">
- </attribute>
+ </attribute>
+</extension>
+<extension
+ id="javaLineBreakpoint"
+ point="org.eclipse.core.resources.markers">
+ <super
+ type="org.eclipse.jdt.debug.javaBreakpoint">
+ </super>
+ <super
+ type="org.eclipse.debug.core.lineBreakpoint">
+ </super>
+ <persistent
+ value="true">
+ </persistent>
<attribute
name="installCount">
</attribute>
@@ -62,14 +75,11 @@
id="javaExceptionBreakpoint"
point="org.eclipse.core.resources.markers">
<super
- type="org.eclipse.debug.core.breakpoint">
+ type="org.eclipse.jdt.debug.javaBreakpoint">
</super>
<persistent
value="true">
- </persistent>
- <attribute
- name="typeHandle">
- </attribute>
+ </persistent>
<attribute
name="caught">
</attribute>
@@ -86,9 +96,9 @@
<super
type="org.eclipse.jdt.debug.javaLineBreakpoint">
</super>
- <persistent
- value="true">
- </persistent>
+ <persistent
+ value="true">
+ </persistent>
<attribute
name="fieldHandle">
</attribute>
@@ -115,4 +125,10 @@
name="methodHandle">
</attribute>
</extension>
+<extension point = "org.eclipse.debug.core.breakpoint_factories">
+<breakpoint_factory
+ id="org.eclipse.jdt.core.JavaBreakpointFactory"
+ class="org.eclipse.jdt.internal.debug.core.JavaBreakpointFactory"
+ type="org.eclipse.jdt.debug.javaBreakpoint"/>
+</extension>
</plugin>