/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Jesper Steen Moller - Enhancement 254677 - filter getters/setters *******************************************************************************/ package org.eclipse.jdt.internal.debug.ui; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IBreakpointsListener; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchListener; import org.eclipse.debug.core.model.IBreakpoint; import org.eclipse.debug.core.model.IDebugTarget; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.sourcelookup.ISourceLookupResult; import org.eclipse.jdt.core.dom.Message; import org.eclipse.jdt.debug.core.IJavaBreakpoint; import org.eclipse.jdt.debug.core.IJavaBreakpointListener; import org.eclipse.jdt.debug.core.IJavaDebugTarget; import org.eclipse.jdt.debug.core.IJavaExceptionBreakpoint; import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.eclipse.jdt.debug.core.IJavaMethodBreakpoint; import org.eclipse.jdt.debug.core.IJavaMethodEntryBreakpoint; import org.eclipse.jdt.debug.core.IJavaStackFrame; import org.eclipse.jdt.debug.core.IJavaThread; import org.eclipse.jdt.debug.core.IJavaType; import org.eclipse.jdt.debug.core.IJavaWatchpoint; import org.eclipse.jdt.debug.core.JDIDebugModel; import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants; import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint; import org.eclipse.jdt.internal.debug.core.logicalstructures.IJavaStructuresListener; import org.eclipse.jdt.internal.debug.core.logicalstructures.JavaLogicalStructures; import org.eclipse.jdt.internal.debug.ui.actions.JavaBreakpointPropertiesAction; import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnCompilationErrorListener; import org.eclipse.jdt.internal.debug.ui.breakpoints.SuspendOnUncaughtExceptionListener; import org.eclipse.jdt.internal.debug.ui.snippeteditor.ScrapbookLauncher; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import com.sun.jdi.InvocationException; import com.sun.jdi.ObjectReference; /** * Manages options for the Java Debugger:<ul> * <li>Suspend on compilation errors</li> * <li>Suspend on uncaught exceptions</li> * <li>Step filters</li> * <li>Sets a system property that the Java debugger is active if * there are launches that contain running debug targets. Used for Java * debug action visibility. * </ul> */ public class JavaDebugOptionsManager implements IDebugEventSetListener, IPropertyChangeListener, IJavaBreakpointListener, ILaunchListener, IBreakpointsListener, IJavaStructuresListener { /** * Singleton options manager */ private static JavaDebugOptionsManager fgOptionsManager = null; /** * Breakpoint used to suspend on uncaught exceptions */ private IJavaExceptionBreakpoint fSuspendOnExceptionBreakpoint = null; /** * Breakpoint used to suspend on compilation errors */ private IJavaExceptionBreakpoint fSuspendOnErrorBreakpoint = null; /** * A label provider */ private static ILabelProvider fLabelProvider= DebugUITools.newDebugModelPresentation(); /** * Constants indicating whether a breakpoint * is added, removed, or changed. */ private static final int ADDED = 0; private static final int REMOVED = 1; private static final int CHANGED = 2; /** * Local cache of active step filters. */ private String[] fActiveStepFilters = null; /** * Preferences that affect variable display options. * * @since 3.3 */ private static Set<String> fgDisplayOptions; static { fgDisplayOptions = new HashSet<>(); fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_CHAR); fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_HEX); fgDisplayOptions.add(IJDIPreferencesConstants.PREF_SHOW_UNSIGNED); } /** * Whether the manager has been activated */ private boolean fActivated = false; class InitJob extends Job { public InitJob() { super(DebugUIMessages.JavaDebugOptionsManager_0); } @Override protected IStatus run(IProgressMonitor monitor) { MultiStatus status = new MultiStatus(JDIDebugUIPlugin.getUniqueIdentifier(), IJavaDebugUIConstants.INTERNAL_ERROR, "Java debug options failed to initialize", null); //$NON-NLS-1$ // compilation error breakpoint try { IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(ResourcesPlugin.getWorkspace().getRoot(),"java.lang.Error", true, true, false, false, null); //$NON-NLS-1$ bp.setPersisted(false); bp.addBreakpointListener(SuspendOnCompilationErrorListener.ID_COMPILATION_ERROR_LISTENER); setSuspendOnCompilationErrorsBreakpoint(bp); } catch (CoreException e) { status.add(e.getStatus()); } // uncaught exception breakpoint try { IJavaExceptionBreakpoint bp = JDIDebugModel.createExceptionBreakpoint(ResourcesPlugin.getWorkspace().getRoot(),"java.lang.Throwable", false, true, false, false, null); //$NON-NLS-1$ ((JavaExceptionBreakpoint)bp).setSuspendOnSubclasses(true); bp.setPersisted(false); bp.addBreakpointListener(SuspendOnUncaughtExceptionListener.ID_UNCAUGHT_EXCEPTION_LISTENER); setSuspendOnUncaughtExceptionBreakpoint(bp); } catch (CoreException e) { status.add(e.getStatus()); } if (status.getChildren().length == 0) { return Status.OK_STATUS; } return status; } } /** * Not to be instantiated * * @see JavaDebugOptionsManager#getDefault(); */ private JavaDebugOptionsManager() { } /** * Return the default options manager */ public static JavaDebugOptionsManager getDefault() { if (fgOptionsManager == null) { fgOptionsManager = new JavaDebugOptionsManager(); } return fgOptionsManager; } /** * Called at startup by the Java debug ui plug-in */ public void startup() { // lazy initialization will occur on the first launch DebugPlugin debugPlugin = DebugPlugin.getDefault(); debugPlugin.getLaunchManager().addLaunchListener(this); debugPlugin.getBreakpointManager().addBreakpointListener(this); EvaluationContextManager.startup(); } /** * Called at shutdown by the Java debug ui plug-in */ public void shutdown() { DebugPlugin debugPlugin = DebugPlugin.getDefault(); debugPlugin.removeDebugEventListener(this); debugPlugin.getLaunchManager().removeLaunchListener(this); debugPlugin.getBreakpointManager().removeBreakpointListener(this); if (!JDIDebugUIPlugin.getDefault().isShuttingDown()) { //avert restoring the preference store at shutdown JDIDebugUIPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this); } JDIDebugModel.removeJavaBreakpointListener(this); JavaLogicalStructures.removeStructuresListener(this); System.getProperties().remove(JDIDebugUIPlugin.getUniqueIdentifier() + ".debuggerActive"); //$NON-NLS-1$ } /** * Initializes compilation error handling and suspending * on uncaught exceptions. */ protected void initializeProblemHandling() { InitJob job = new InitJob(); job.setSystem(true); job.schedule(); } /** * Notifies java debug targets of the given breakpoint * addition or removal. * * @param breakpoint a breakpoint * @param kind ADDED, REMOVED, or CHANGED */ protected void notifyTargets(IBreakpoint breakpoint, int kind) { IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets(); for (int i = 0; i < targets.length; i++) { if (targets[i] instanceof IJavaDebugTarget) { IJavaDebugTarget target = (IJavaDebugTarget)targets[i]; notifyTarget(target, breakpoint, kind); } } } /** * Notifies the give debug target of filter specifications * * @param target Java debug target */ protected void notifyTargetOfFilters(IJavaDebugTarget target) { IPreferenceStore store = JDIDebugUIPlugin.getDefault().getPreferenceStore(); target.setFilterConstructors(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS)); target.setFilterStaticInitializers(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS)); target.setFilterSynthetics(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS)); target.setFilterGetters(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_GETTERS)); target.setFilterSetters(store.getBoolean(IJDIPreferencesConstants.PREF_FILTER_SETTERS)); target.setStepThruFilters(store.getBoolean(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS)); target.setStepFilters(getActiveStepFilters()); } /** * Notifies all targets of current filter specifications. */ protected void notifyTargetsOfFilters() { IDebugTarget[] targets = DebugPlugin.getDefault().getLaunchManager().getDebugTargets(); for (int i = 0; i < targets.length; i++) { if (targets[i] instanceof IJavaDebugTarget) { IJavaDebugTarget target = (IJavaDebugTarget)targets[i]; notifyTargetOfFilters(target); } } } /** * Notifies the given target of the given breakpoint * addition or removal. * * @param target Java debug target * @param breakpoint a breakpoint * @param kind ADDED, REMOVED, or CHANGED */ protected void notifyTarget(IJavaDebugTarget target, IBreakpoint breakpoint, int kind) { switch (kind) { case ADDED: target.breakpointAdded(breakpoint); break; case REMOVED: target.breakpointRemoved(breakpoint,null); break; case CHANGED: target.breakpointChanged(breakpoint,null); break; } } /** * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent) */ @Override public void propertyChange(PropertyChangeEvent event) { String property = event.getProperty(); if (property.equals(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS)) { IBreakpoint breakpoint = getSuspendOnCompilationErrorBreakpoint(); if (breakpoint != null) { int kind = REMOVED; if (isSuspendOnCompilationErrors()) { kind = ADDED; } notifyTargets(breakpoint, kind); } } else if (property.equals(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS)) { IBreakpoint breakpoint = getSuspendOnUncaughtExceptionBreakpoint(); if (breakpoint != null) { int kind = REMOVED; if (isSuspendOnUncaughtExceptions()) { kind = ADDED; } notifyTargets(breakpoint, kind); } } else if (fgDisplayOptions.contains(property)) { variableViewSettingsChanged(); } else if (isUseFilterProperty(property)) { notifyTargetsOfFilters(); } else if (isFilterListProperty(property)) { updateActiveFilters(); } } /** * Returns whether the given property is a property that affects whether * or not step filters are used. */ private boolean isUseFilterProperty(String property) { return property.equals(IJDIPreferencesConstants.PREF_FILTER_CONSTRUCTORS) || property.equals(IJDIPreferencesConstants.PREF_FILTER_STATIC_INITIALIZERS) || property.equals(IJDIPreferencesConstants.PREF_FILTER_GETTERS) || property.equals(IJDIPreferencesConstants.PREF_FILTER_SETTERS) || property.equals(IJDIPreferencesConstants.PREF_FILTER_SYNTHETICS) || property.equals(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS); } /** * Returns whether the given property is a property that affects * the list of active or inactive step filters. */ private boolean isFilterListProperty(String property) { return property.equals(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST) || property.equals(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST); } /** * Enable/Disable the given breakpoint and notify * targets of the change. * * @param breakpoint a breakpoint * @param enabled whether enabeld */ protected void setEnabled(IBreakpoint breakpoint, boolean enabled) { try { breakpoint.setEnabled(enabled); notifyTargets(breakpoint, CHANGED); } catch (CoreException e) { JDIDebugUIPlugin.log(e); } } /** * Returns whether suspend on compilation errors is * enabled. * * @return whether suspend on compilation errors is * enabled */ public boolean isSuspendOnCompilationErrors() { return JDIDebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_COMPILATION_ERRORS); } /** * Returns whether suspend on uncaught exception is * enabled * * @return whether suspend on uncaught exception is * enabled */ protected boolean isSuspendOnUncaughtExceptions() { return JDIDebugUIPlugin.getDefault().getPreferenceStore().getBoolean(IJDIPreferencesConstants.PREF_SUSPEND_ON_UNCAUGHT_EXCEPTIONS); } /** * Sets the breakpoint used to suspend on uncaught exceptions * * @param breakpoint exception breakpoint */ private void setSuspendOnUncaughtExceptionBreakpoint(IJavaExceptionBreakpoint breakpoint) { fSuspendOnExceptionBreakpoint = breakpoint; } /** * Returns the breakpoint used to suspend on uncaught exceptions * * @return exception breakpoint */ protected IJavaExceptionBreakpoint getSuspendOnUncaughtExceptionBreakpoint() { return fSuspendOnExceptionBreakpoint; } /** * Sets the breakpoint used to suspend on compilation * errors. * * @param breakpoint exception breakpoint */ private void setSuspendOnCompilationErrorsBreakpoint(IJavaExceptionBreakpoint breakpoint) { fSuspendOnErrorBreakpoint = breakpoint; } /** * Returns the breakpoint used to suspend on compilation * errors * * @return exception breakpoint */ protected IJavaExceptionBreakpoint getSuspendOnCompilationErrorBreakpoint() { return fSuspendOnErrorBreakpoint; } /** * Parses the comma separated string into an array of strings * * @return list */ public static String[] parseList(String listString) { List<String> list = new ArrayList<>(10); StringTokenizer tokenizer = new StringTokenizer(listString, ","); //$NON-NLS-1$ while (tokenizer.hasMoreTokens()) { String token = tokenizer.nextToken(); list.add(token); } return list.toArray(new String[list.size()]); } /** * Serializes the array of strings into one comma * separated string. * * @param list array of strings * @return a single string composed of the given list */ public static String serializeList(String[] list) { if (list == null) { return ""; //$NON-NLS-1$ } StringBuffer buffer = new StringBuffer(); for (int i = 0; i < list.length; i++) { if (i > 0) { buffer.append(','); } buffer.append(list[i]); } return buffer.toString(); } /** * Returns the current list of active step filters. * * @return current list of active step filters */ protected String[] getActiveStepFilters() { if (fActiveStepFilters == null) { fActiveStepFilters= parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST)); // After active filters are cached, register to hear about future changes JDIDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this); } return fActiveStepFilters; } /** * Updates local copy of active step filters and * notifies targets. */ protected void updateActiveFilters() { fActiveStepFilters= parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_ACTIVE_FILTERS_LIST)); notifyTargetsOfFilters(); } /** * When a Java debug target is created, install options in * the target and set that the Java debugger is active. * When all Java debug targets are terminated set that that Java debugger is * no longer active. * * @see IDebugEventSetListener#handleDebugEvents(DebugEvent[]) */ @Override public void handleDebugEvents(DebugEvent[] events) { for (int i = 0; i < events.length; i++) { DebugEvent event = events[i]; if (event.getKind() == DebugEvent.CREATE) { Object source = event.getSource(); if (source instanceof IJavaDebugTarget) { IJavaDebugTarget javaTarget = (IJavaDebugTarget)source; // compilation breakpoints if (isSuspendOnCompilationErrors()) { notifyTarget(javaTarget, getSuspendOnCompilationErrorBreakpoint(), ADDED); } // uncaught exception breakpoint if (isSuspendOnUncaughtExceptions()) { ILaunchConfiguration launchConfiguration = javaTarget.getLaunch().getLaunchConfiguration(); boolean isSnippetEditor = false; try { isSnippetEditor = (launchConfiguration.getAttribute(ScrapbookLauncher.SCRAPBOOK_LAUNCH, (String)null) != null); } catch (CoreException e) { } if (!isSnippetEditor) { notifyTarget(javaTarget, getSuspendOnUncaughtExceptionBreakpoint(), ADDED); } } // step filters notifyTargetOfFilters(javaTarget); } } } } /** * @see IJavaBreakpointListener#addingBreakpoint(IJavaDebugTarget, IJavaBreakpoint) */ @Override public void addingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { } /** * @see IJavaBreakpointListener#installingBreakpoint(IJavaDebugTarget, IJavaBreakpoint, IJavaType) */ @Override public int installingBreakpoint(IJavaDebugTarget target, IJavaBreakpoint breakpoint, IJavaType type) { return DONT_CARE; } /** * @see IJavaBreakpointListener#breakpointHit(IJavaThread, IJavaBreakpoint) */ @Override public int breakpointHit(IJavaThread thread, IJavaBreakpoint breakpoint) { return DONT_CARE; } /** * @see IJavaBreakpointListener#breakpointInstalled(IJavaDebugTarget, IJavaBreakpoint) */ @Override public void breakpointInstalled(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { } /** * @see IJavaBreakpointListener#breakpointRemoved(IJavaDebugTarget, IJavaBreakpoint) */ @Override public void breakpointRemoved(IJavaDebugTarget target, IJavaBreakpoint breakpoint) { } /** * Returns any problem marker associated with the current location * of the given stack frame, or <code>null</code> if none. * * @param frame stack frame * @return marker representing compilation problem, or <code>null</code> * @throws DebugException if an exception occurrs retrieveing the problem */ public IMarker getProblem(IJavaStackFrame frame) { ILaunch launch = frame.getLaunch(); if (launch != null) { ISourceLookupResult result = DebugUITools.lookupSource(frame, null); Object sourceElement = result.getSourceElement(); if (sourceElement instanceof IResource) { try { IResource resource = (IResource) sourceElement; IMarker[] markers = resource.findMarkers("org.eclipse.jdt.core.problem", true, IResource.DEPTH_INFINITE); //$NON-NLS-1$ int line = frame.getLineNumber(); for (int i = 0; i < markers.length; i++) { IMarker marker = markers[i]; if (marker.getAttribute(IMarker.LINE_NUMBER, -1) == line && marker.getAttribute(IMarker.SEVERITY, -1) == IMarker.SEVERITY_ERROR) { return marker; } } } catch (CoreException e) { } } } return null; } /* (non-Javadoc) * @see org.eclipse.jdt.debug.core.IJavaBreakpointListener#breakpointHasRuntimeException(org.eclipse.jdt.debug.core.IJavaLineBreakpoint, org.eclipse.debug.core.DebugException) */ @Override public void breakpointHasRuntimeException(final IJavaLineBreakpoint breakpoint, final DebugException exception) { IStatus status; Throwable wrappedException= exception.getStatus().getException(); if (wrappedException instanceof InvocationException) { InvocationException ie= (InvocationException) wrappedException; ObjectReference ref= ie.exception(); status= new Status(IStatus.ERROR,JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, ref.referenceType().name(), null); } else { status= exception.getStatus(); } openConditionErrorDialog(breakpoint, DebugUIMessages.JavaDebugOptionsManager_Conditional_breakpoint_encountered_runtime_exception__1, status); } /* (non-Javadoc) * @see org.eclipse.jdt.debug.core.IJavaBreakpointListener#breakpointHasCompilationErrors(org.eclipse.jdt.debug.core.IJavaLineBreakpoint, org.eclipse.jdt.core.dom.Message[]) */ @Override public void breakpointHasCompilationErrors(final IJavaLineBreakpoint breakpoint, final Message[] errors) { StringBuffer message= new StringBuffer(); Message error; for (int i=0, numErrors= errors.length; i < numErrors; i++) { error= errors[i]; message.append(error.getMessage()); message.append("\n "); //$NON-NLS-1$ } IStatus status= new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, message.toString(), null); openConditionErrorDialog(breakpoint, DebugUIMessages.JavaDebugOptionsManager_Conditional_breakpoint_has_compilation_error_s___2, status); } private void openConditionErrorDialog(final IJavaLineBreakpoint breakpoint, final String errorMessage, final IStatus status) { final Display display= JDIDebugUIPlugin.getStandardDisplay(); if (display.isDisposed()) { return; } final String message= NLS.bind(errorMessage, new String[] {fLabelProvider.getText(breakpoint)}); display.asyncExec(new Runnable() { @Override public void run() { if (display.isDisposed()) { return; } Shell shell= JDIDebugUIPlugin.getActiveWorkbenchShell(); ConditionalBreakpointErrorDialog dialog= new ConditionalBreakpointErrorDialog(shell, message, status); int result = dialog.open(); if (result == Window.OK) { JavaBreakpointPropertiesAction action= new JavaBreakpointPropertiesAction(); action.selectionChanged(null, new StructuredSelection(breakpoint)); action.run(null); } } }); } /** * Activates this debug options manager. When active, this * manager becomes a listener to many notifications and updates * running debug targets based on these notifications. * * A debug options manager does not need to be activated until * there is a running debug target. */ private void activate() { if (fActivated) { return; } fActivated = true; initializeProblemHandling(); notifyTargetsOfFilters(); DebugPlugin.getDefault().addDebugEventListener(this); JDIDebugModel.addJavaBreakpointListener(this); JavaLogicalStructures.addStructuresListener(this); } /** * Startup problem handling on the first launch. * * @see ILaunchListener#launchAdded(ILaunch) */ @Override public void launchAdded(ILaunch launch) { launchChanged(launch); } /** * @see ILaunchListener#launchChanged(ILaunch) */ @Override public void launchChanged(ILaunch launch) { activate(); DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); } /** * @see ILaunchListener#launchRemoved(ILaunch) */ @Override public void launchRemoved(ILaunch launch) { } /** * Adds message attributes to java breakpoints. * * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[]) */ @Override public void breakpointsAdded(final IBreakpoint[] breakpoints) { // if a breakpoint is added, but already has a message, do not update it List<IBreakpoint> update = new ArrayList<>(); for (int i = 0; i < breakpoints.length; i++) { IBreakpoint breakpoint = breakpoints[i]; try { if (breakpoint instanceof IJavaBreakpoint && breakpoint.getMarker().getAttribute(IMarker.MESSAGE) == null) { update.add(breakpoint); } } catch (CoreException e) { JDIDebugUIPlugin.log(e); } } if (!update.isEmpty()) { updateBreakpointMessages(update.toArray(new IBreakpoint[update.size()])); } } /** * Updates message attributes on the given java breakpoints. * * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsAdded(org.eclipse.debug.core.model.IBreakpoint[]) */ private void updateBreakpointMessages(final IBreakpoint[] breakpoints) { IWorkspaceRunnable runnable = new IWorkspaceRunnable() { @Override public void run(IProgressMonitor monitor) throws CoreException { for (int i = 0; i < breakpoints.length; i++) { IBreakpoint breakpoint = breakpoints[i]; if (breakpoint instanceof IJavaBreakpoint) { String info = fLabelProvider.getText(breakpoint); String type = DebugUIMessages.JavaDebugOptionsManager_Breakpoint___1; if (breakpoint instanceof IJavaMethodBreakpoint || breakpoint instanceof IJavaMethodEntryBreakpoint) { type = DebugUIMessages.JavaDebugOptionsManager_Method_breakpoint___2; } else if (breakpoint instanceof IJavaWatchpoint) { type = DebugUIMessages.JavaDebugOptionsManager_Watchpoint___3; } else if (breakpoint instanceof IJavaLineBreakpoint) { type = DebugUIMessages.JavaDebugOptionsManager_Line_breakpoint___4; } breakpoint.getMarker().setAttribute(IMarker.MESSAGE, type + info); } } } }; try { ResourcesPlugin.getWorkspace().run(runnable, null, 0, null); } catch (CoreException e) { JDIDebugUIPlugin.log(e); } } /** * Updates message attributes on java breakpoints. * * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsChanged(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[]) */ @Override public void breakpointsChanged( IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { updateBreakpointMessages(breakpoints); } /* (non-Javadoc) * @see org.eclipse.debug.core.IBreakpointsListener#breakpointsRemoved(org.eclipse.debug.core.model.IBreakpoint[], org.eclipse.core.resources.IMarkerDelta[]) */ @Override public void breakpointsRemoved( IBreakpoint[] breakpoints, IMarkerDelta[] deltas) { } /* (non-Javadoc) * @see org.eclipse.jdt.internal.debug.core.logicalstructures.IJavaStructuresListener#logicalStructuresChanged() */ @Override public void logicalStructuresChanged() { variableViewSettingsChanged(); } /** * Refreshes the variables view by firing a change event on a stack frame (active * debug context). */ protected void variableViewSettingsChanged() { // If a Java stack frame is selected in the Debug view, fire a change event on // it so the variables view will update for any structure changes. IAdaptable selected = DebugUITools.getDebugContext(); if (selected != null) { IJavaStackFrame frame = selected.getAdapter(IJavaStackFrame.class); if (frame != null) { DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { new DebugEvent(frame, DebugEvent.CHANGE) }); } } } }