From ceb1b0efad04ed094925d3fb06f690658956314a Mon Sep 17 00:00:00 2001 From: Ken Ryall Date: Fri, 25 Jan 2008 22:58:17 +0000 Subject: [PATCH] Bugs 216092 & 211533. --- debug/org.eclipse.cdt.debug.core/plugin.xml | 10 ++ .../schema/BreakpointExtension.exsd | 127 ++++++++++++++ .../cdt/debug/core/CDebugCorePlugin.java | 4 + .../cdt/debug/core/model/ICBreakpoint.java | 62 +------ .../core/model/ICBreakpointExtension.java | 43 +++++ .../model/ICBreakpointFilterExtension.java | 81 +++++++++ .../internal/core/CBreakpointManager.java | 35 ++-- .../core/breakpoints/BreakpointProblems.java | 9 +- .../core/breakpoints/CBreakpoint.java | 155 ++++++++++-------- .../CBreakpointFilterExtension.java | 96 +++++++++++ debug/org.eclipse.cdt.debug.ui/plugin.xml | 8 +- .../debug/internal/ui/CBreakpointContext.java | 136 +++++++++++++++ .../internal/ui/ICDebugHelpContextIds.java | 3 + .../actions/CBreakpointPropertiesAction.java | 18 +- .../CBreakpointPropertiesRulerAction.java | 22 ++- .../CBreakpointFilteringPage.java | 18 +- .../CBreakpointPropertyPage.java | 2 +- .../ui/propertypages/ThreadFilterEditor.java | 19 ++- 18 files changed, 679 insertions(+), 169 deletions(-) create mode 100644 debug/org.eclipse.cdt.debug.core/schema/BreakpointExtension.exsd create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointFilterExtension.java create mode 100644 debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpointFilterExtension.java create mode 100644 debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/CBreakpointContext.java diff --git a/debug/org.eclipse.cdt.debug.core/plugin.xml b/debug/org.eclipse.cdt.debug.core/plugin.xml index c81340d9808..0ce2a273de2 100644 --- a/debug/org.eclipse.cdt.debug.core/plugin.xml +++ b/debug/org.eclipse.cdt.debug.core/plugin.xml @@ -4,6 +4,7 @@ + + + + + diff --git a/debug/org.eclipse.cdt.debug.core/schema/BreakpointExtension.exsd b/debug/org.eclipse.cdt.debug.core/schema/BreakpointExtension.exsd new file mode 100644 index 00000000000..294b1dbc8e0 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/schema/BreakpointExtension.exsd @@ -0,0 +1,127 @@ + + + + + + + + + This extension point defines a mechanism for defining a debug model specific extension to C breakpoints. + + + + + + + + + + + + a fully qualified identifier of the target extension point + + + + + + + an optional identifier of the extension instance + + + + + + + an optional name of the extension instance + + + + + + + + + + + + specifies a unique identifier for this breakpoint extension type. + + + + + + + specifies the fully qualified identifier (id) of the corresponding marker definition for breakpoints that this extension applies to + + + + + + + specifies the fully qualified name of the Java class that implements <code>ICBreakpointExtension</code>. + + + + + + + + + + specifies the fully qualified identifer (id) of the debug model that this extension applies to + + + + + + + + + + + + + The following is an example of a breakpoint extension extension point. + +<p> +<pre> + <extension point="org.eclipse.cdt.debug.BreakpointExtension"> + <breakpointExtension + id="com.example.ExampleBreakpointExtension" + markerType="com.example.ExampleBreakpointMarker" + debugModeId="com.example.debug" + class="com.example.BreakpointExtensionImpl"> + </breakpointExtension> + </extension> +</pre> +</p> + +In the example above, the specified type of breakpoint extension is implemented by the class "com.example.BreakpointExtensionImpl". +This extension is going to apply to breakpoints with markers extending "com.example.ExampleBreakpointMarker", and to debug model with ID of "com.example.debug". + + + + + + + + + Value of the attribute <b>class</b> must be a fully qualified name of a Java class that implements the interface <b>org.eclipse.cdt.debug.core.model.ICBreakpointExtension</b>, and which supplies a constructor with a single argument of type <b>org.eclipse.cdt.debug.core.model.ICBreakpoint</b>. + + + + + + + + + + Copyright (c) 2007 Wind River Systems and others.<br> +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 +<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a> + + + + diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java index 05861f35b36..750dfc92f90 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/CDebugCorePlugin.java @@ -83,6 +83,10 @@ public class CDebugCorePlugin extends Plugin { public static final String BREAKPOINT_ACTION_EXTENSION_POINT_ID = "BreakpointActionType"; //$NON-NLS-1$ public static final String ACTION_TYPE_ELEMENT = "actionType"; //$NON-NLS-1$ + public static final String BREAKPOINT_EXTENSION_EXTENSION_POINT_ID = "BreakpointExtension"; //$NON-NLS-1$ + public static final String BREAKPOINT_EXTENSION_ELEMENT = "breakpointExtension"; //$NON-NLS-1$ + + /** * Dummy source lookup director needed to manage common source containers. */ diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint.java index 8eff3bd567e..115bac421ff 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpoint.java @@ -206,61 +206,13 @@ public interface ICBreakpoint extends IBreakpoint { public void resetInstallCount() throws CoreException; /** - * Add the given target to the list of this breakpoint's targets. - * Target filters are not persisted across workbench invocations. + * Returns a breakpoint extension registered for the given debug model + * and of the given type. * - * @param target the target to add to the list of this breakpoint's targets. - * @throws CoreException if unable to set the target filter + * @param debugModelId Debug model ID of the extension. + * @param extensionType Type of the extension. + * @return Extension instance. + * @throws CoreException Throws exception in case the extension doesn't exist or cannot be initialized. */ - public void setTargetFilter( ICDebugTarget target ) throws CoreException; - - /** - * Removes the given target from the breakpoint's target list. - * The breakpoint has no effect in the given target. - * - * @param target the target filter to be removed - * @exception CoreException if unable to remove the target filter - */ - public void removeTargetFilter( ICDebugTarget target ) throws CoreException; - - /** - * Restricts this breakpoint to suspend only in the given threads - * when encounterd in the given threads' target. - * All threads must be from the same target. - * Thread filters are not persisted across workbench invocations. - * - * @param threads the thread filters to be set - * @exception CoreException if unable to set the thread filters - */ - public void setThreadFilters( ICThread[] threads ) throws CoreException; - - /** - * Returns all target filters set on this breakpoint. - * - * @return the targets that this breakpoint is resticted to - * @exception CoreException if unable to determine this breakpoint's - * target filters - */ - public ICDebugTarget[] getTargetFilters() throws CoreException; - - /** - * Removes this breakpoint's thread filters in the given target, if any. - * Has no effect if this breakpoint does not have filters in the given target. - * All threads must be from the same target. - * - * @param threads the thread filters to be removed - * @exception CoreException if unable to remove the thread filter - */ - public void removeThreadFilters( ICThread[] threads ) throws CoreException; - - /** - * Returns the threads in the given target in which this breakpoint - * is enabled or null if this breakpoint is enabled in - * all threads in the given target. - * - * @return the threads in the given target that this breakpoint is enabled for - * @exception CoreException if unable to determine this breakpoint's thread - * filters - */ - public ICThread[] getThreadFilters( ICDebugTarget target ) throws CoreException; + public ICBreakpointExtension getExtension(String debugModelId, Class extensionType) throws CoreException ; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java new file mode 100644 index 00000000000..3b9863f9e2e --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointExtension.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.core.runtime.CoreException; + +/** + * An extension to {@link ICBreakpoint} with model-specific breakpoint + * attributes. Different debug models can use the standard C breakpoints that + * extend the basic ICBreakpiont. The can use this extension + * mechanism to edit and store model-specific data in the original breakpoint + * object. + * + * A breakpoint extension is defined by an extension of kind + * "org.eclipse.cdt.debug.core.BreakpointExtension". + * The ICBreakpoint implementation instantiates breakpoint + * extensions registered for its specific marker type when a client requests + * extensions for a given debug model type. Thus the extension classes and + * plugins that declare them are not loaded unless requested by a client. + * + * @see ICBreakpoint#getExtension(String, Class) + */ +public interface ICBreakpointExtension { + + /** + * Initializes the extension with the given breakpoint instance. + * The breakpoint extension may initialize its data using attributes + * stored in the breakpoint marker. + * + * @param breakpoint Breakpoint instance that this extension belongs to. + * @throws CoreException Thrown in case of errors reading the breakpoint + * marker. + */ + public void initialize(ICBreakpoint breakpoint) throws CoreException; +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointFilterExtension.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointFilterExtension.java new file mode 100644 index 00000000000..f5bc52ecef6 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/ICBreakpointFilterExtension.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 QNX Software Systems 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: + * QNX Software Systems - Initial API and implementation + * Wind River Systems - Refactored from ICBreakpoint + *******************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.core.runtime.CoreException; + +/** + * Breakpoint extension to allow filtering based on CDTs extended standard debug + * model elements. + */ +public interface ICBreakpointFilterExtension extends ICBreakpointExtension { + + /** + * Add the given target to the list of this breakpoint's targets. + * Target filters are not persisted across workbench invocations. + * + * @param target the target to add to the list of this breakpoint's targets. + * @throws CoreException if unable to set the target filter + */ + public void setTargetFilter( ICDebugTarget target ) throws CoreException; + + /** + * Removes the given target from the breakpoint's target list. + * The breakpoint has no effect in the given target. + * + * @param target the target filter to be removed + * @exception CoreException if unable to remove the target filter + */ + public void removeTargetFilter( ICDebugTarget target ) throws CoreException; + + /** + * Restricts this breakpoint to suspend only in the given threads + * when encounterd in the given threads' target. + * All threads must be from the same target. + * Thread filters are not persisted across workbench invocations. + * + * @param threads the thread filters to be set + * @exception CoreException if unable to set the thread filters + */ + public void setThreadFilters( ICThread[] threads ) throws CoreException; + + /** + * Returns all target filters set on this breakpoint. + * + * @return the targets that this breakpoint is resticted to + * @exception CoreException if unable to determine this breakpoint's + * target filters + */ + public ICDebugTarget[] getTargetFilters() throws CoreException; + + /** + * Removes this breakpoint's thread filters in the given target, if any. + * Has no effect if this breakpoint does not have filters in the given target. + * All threads must be from the same target. + * + * @param threads the thread filters to be removed + * @exception CoreException if unable to remove the thread filter + */ + public void removeThreadFilters( ICThread[] threads ) throws CoreException; + + /** + * Returns the threads in the given target in which this breakpoint + * is enabled or null if this breakpoint is enabled in + * all threads in the given target. + * + * @return the threads in the given target that this breakpoint is enabled for + * @exception CoreException if unable to determine this breakpoint's thread + * filters + */ + public ICThread[] getThreadFilters( ICDebugTarget target ) throws CoreException; + +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java index 11132cb0136..8c3e002ed66 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java @@ -24,6 +24,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; + import org.eclipse.cdt.core.IAddress; import org.eclipse.cdt.core.IAddressFactory; import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; @@ -50,20 +51,21 @@ import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpointManagement2; import org.eclipse.cdt.debug.core.cdi.model.ICDIFunctionBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILineBreakpoint; import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint; -import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint2; import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration; import org.eclipse.cdt.debug.core.cdi.model.ICDITargetConfiguration2; import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint2; import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; -import org.eclipse.cdt.debug.core.model.ICWatchpoint2; import org.eclipse.cdt.debug.core.model.ICThread; import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint2; import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; import org.eclipse.cdt.debug.internal.core.breakpoints.BreakpointProblems; import org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint; @@ -329,7 +331,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana ICBreakpoint b = (ICBreakpoint)breakpoints[i]; boolean install = false; try { - ICDebugTarget[] tfs = b.getTargetFilters(); + ICDebugTarget[] tfs = getFilterExtension(b).getTargetFilters(); install = Arrays.asList( tfs ).contains( getDebugTarget() ); } catch( CoreException e ) { @@ -484,7 +486,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana try { BreakpointProblems.removeProblemsForResolvedBreakpoint(breakpoint, getDebugTarget().getInternalID()); - breakpoint.setTargetFilter( getDebugTarget() ); + getFilterExtension(breakpoint).setTargetFilter( getDebugTarget() ); ((CBreakpoint)breakpoint).register( true ); } catch( CoreException e ) { @@ -513,7 +515,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana if ( breakpoint != null ) { try { - breakpoint.setTargetFilter( getDebugTarget() ); + getFilterExtension(breakpoint).setTargetFilter( getDebugTarget() ); ((CBreakpoint)breakpoint).register( true ); } catch( CoreException e ) { @@ -532,8 +534,10 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana int newLineNumber = movedEvent.getNewLocation().getLineNumber(); int currLineNumber = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, newLineNumber); breakpoint.getMarker().setAttribute(IMarker.LINE_NUMBER, newLineNumber); - fBreakpointProblems.add(BreakpointProblems.reportBreakpointMoved( - breakpoint, currLineNumber, newLineNumber, getDebugTarget().getName(), getDebugTarget().getInternalID())); + IMarker marker = BreakpointProblems.reportBreakpointMoved( + breakpoint, currLineNumber, newLineNumber, getDebugTarget().getName(), getDebugTarget().getInternalID()); + if (marker != null) + fBreakpointProblems.add(marker); } catch (CoreException e) {} } @@ -612,7 +616,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana if ( breakpoint != null ) { if ( isFilteredByTarget( breakpoint, getDebugTarget() ) ) { try { - breakpoint.removeTargetFilter( getDebugTarget() ); + getFilterExtension(breakpoint).removeTargetFilter( getDebugTarget() ); } catch( CoreException e ) { } @@ -665,7 +669,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana ICBreakpoint breakpoint = (ICBreakpoint) iter.next(); if ( isFilteredByTarget( breakpoint, target ) ) { try { - breakpoint.removeTargetFilter( target ); + getFilterExtension(breakpoint).removeTargetFilter( target ); } catch( CoreException e ) { CDebugCorePlugin.log( e.getStatus() ); @@ -724,7 +728,9 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana String fileName = breakpoint.getFileName(); ICDIFunctionLocation location = cdiTarget.createFunctionLocation( fileName, function ); ICDICondition condition = createCondition( breakpoint ); - fBreakpointProblems.add(BreakpointProblems.reportUnresolvedBreakpoint(breakpoint, getDebugTarget().getName(), getDebugTarget().getInternalID())); + IMarker marker = BreakpointProblems.reportUnresolvedBreakpoint(breakpoint, getDebugTarget().getName(), getDebugTarget().getInternalID()); + if (marker != null) + fBreakpointProblems.add(marker); if (bpManager2 != null) b = bpManager2.setFunctionBreakpoint( ICDIBreakpoint.REGULAR, location, condition, true, breakpoints[i].isEnabled() ); else @@ -798,7 +804,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana private String[] getThreadNames( ICBreakpoint breakpoint ) { try { - ICThread[] threads = breakpoint.getThreadFilters( getDebugTarget() ); + ICThread[] threads = getFilterExtension(breakpoint).getThreadFilters( getDebugTarget() ); if ( threads == null ) return new String[0]; String[] names = new String[threads.length]; @@ -1205,7 +1211,7 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana private boolean isFilteredByTarget( ICBreakpoint breakpoint, ICDebugTarget target ) { boolean result = false; try { - ICDebugTarget[] tfs = breakpoint.getTargetFilters(); + ICDebugTarget[] tfs = getFilterExtension(breakpoint).getTargetFilters(); result = Arrays.asList( tfs ).contains( target ); } catch( CoreException e ) { @@ -1230,4 +1236,9 @@ public class CBreakpointManager implements IBreakpointsListener, IBreakpointMana } return false; } + + private ICBreakpointFilterExtension getFilterExtension(ICBreakpoint bp) throws CoreException{ + return (ICBreakpointFilterExtension)bp.getExtension( + CDIDebugModel.getPluginIdentifier(), ICBreakpointFilterExtension.class); + } } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java index 097bccea050..dd3eb2bcb3c 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/BreakpointProblems.java @@ -124,9 +124,12 @@ public class BreakpointProblems { lineBreakpoint.getMarker().getResource(), lineBreakpoint.getLineNumber(), description, severity, "")); //$NON-NLS-1$ - marker.setAttribute(BREAKPOINT_PROBLEM_TYPE, problemType); - marker.setAttribute(BREAKPOINT_CONTEXT_NAME, contextName); - marker.setAttribute(BREAKPOINT_CONTEXT_ID, contextID); + if (marker != null) + { + marker.setAttribute(BREAKPOINT_PROBLEM_TYPE, problemType); + marker.setAttribute(BREAKPOINT_CONTEXT_NAME, contextName); + marker.setAttribute(BREAKPOINT_CONTEXT_ID, contextID); + } } return marker; } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java index d51cbe5d786..b05821f0870 100644 --- a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpoint.java @@ -11,47 +11,55 @@ package org.eclipse.cdt.debug.internal.core.breakpoints; import java.text.MessageFormat; -import java.util.Arrays; +import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; +import java.util.List; import java.util.Map; -import java.util.Set; + import org.eclipse.cdt.debug.core.CDIDebugModel; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.cdt.debug.core.model.ICBreakpoint; -import org.eclipse.cdt.debug.core.model.ICDebugTarget; -import org.eclipse.cdt.debug.core.model.ICThread; +import org.eclipse.cdt.debug.core.model.ICBreakpointExtension; import org.eclipse.core.resources.IMarker; 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.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugEvent; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.IDebugEventSetListener; import org.eclipse.debug.core.model.Breakpoint; -import org.eclipse.debug.core.model.IDebugTarget; /** * The base class for all C/C++ specific breakpoints. */ public abstract class CBreakpoint extends Breakpoint implements ICBreakpoint, IDebugEventSetListener { - private Map fFilteredThreadsByTarget; + /** + * Map of breakpoint extensions. The keys to the map are debug model IDs + * and values are arrays of breakpoint extensions. + */ + private Map fExtensions = new HashMap(1); + + /** + * Constructor for CBreakpoint. + */ + public CBreakpoint() { + } - /** - * Constructor for CBreakpoint. - */ - public CBreakpoint() { - fFilteredThreadsByTarget = new HashMap( 10 ); - } /** * Constructor for CBreakpoint. */ public CBreakpoint( final IResource resource, final String markerType, final Map attributes, final boolean add ) throws CoreException { - this(); + this(); IWorkspaceRunnable wr = new IWorkspaceRunnable() { public void run( IProgressMonitor monitor ) throws CoreException { @@ -282,64 +290,6 @@ public abstract class CBreakpoint extends Breakpoint implements ICBreakpoint, ID return sb.toString(); } - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getTargetFilters() - */ - public ICDebugTarget[] getTargetFilters() throws CoreException { - Set set = fFilteredThreadsByTarget.keySet(); - return (ICDebugTarget[])set.toArray( new ICDebugTarget[set.size()] ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getThreadFilters(org.eclipse.cdt.debug.core.model.ICDebugTarget) - */ - public ICThread[] getThreadFilters( ICDebugTarget target ) throws CoreException { - Set set = (Set)fFilteredThreadsByTarget.get( target ); - return ( set != null ) ? (ICThread[])set.toArray( new ICThread[set.size()] ) : null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) - */ - public void removeTargetFilter( ICDebugTarget target ) throws CoreException { - if ( fFilteredThreadsByTarget.containsKey( target ) ) { - fFilteredThreadsByTarget.remove( target ); - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) - */ - public void removeThreadFilters( ICThread[] threads ) throws CoreException { - if ( threads != null && threads.length > 0 ) { - IDebugTarget target = threads[0].getDebugTarget(); - if ( fFilteredThreadsByTarget.containsKey( target ) ) { - Set set = (Set)fFilteredThreadsByTarget.get( target ); - if ( set != null ) { - set.removeAll( Arrays.asList( threads ) ); - if ( set.isEmpty() ) { - fFilteredThreadsByTarget.remove( target ); - } - } - } - } - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) - */ - public void setTargetFilter( ICDebugTarget target ) throws CoreException { - fFilteredThreadsByTarget.put( target, null ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) - */ - public void setThreadFilters( ICThread[] threads ) throws CoreException { - if ( threads != null && threads.length > 0 ) { - fFilteredThreadsByTarget.put( threads[0].getDebugTarget(), new HashSet( Arrays.asList( threads ) ) ); - } - } /** * Change notification when there are no marker changes. If the marker @@ -365,4 +315,65 @@ public abstract class CBreakpoint extends Breakpoint implements ICBreakpoint, ID public void setModule( String module ) throws CoreException { setAttribute( MODULE, module ); } + + public ICBreakpointExtension getExtension(String debugModelId, Class extensionType) throws CoreException { + ICBreakpointExtension[] extensions = getExtensionsForModelId(debugModelId); + for (int i = 0; i < extensions.length; i++) { + if ( extensionType.isAssignableFrom(extensions[i].getClass()) ) { + return extensions[i]; + } + } + throw new CoreException(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugPlugin.ERROR, "Extension " + extensionType + " not defined for breakpoint " + this, null)); //$NON-NLS-1$ //$NON-NLS-2$ + } + + /** + * Reads platform extension registry for breakpoint extensions registered + * for the given debug model. + * @param debugModelId Requested debug model that the extensions were + * registerd for. + * @return Breakpoint extensions. + * @throws CoreException Throws exception in case the breakpoint marker + * cannot be accessed. + */ + private ICBreakpointExtension[] getExtensionsForModelId(String debugModelId) throws CoreException { + if (!fExtensions.containsKey(debugModelId)) { + // Check to make sure that a marker is present. Extensions can only be created + // once the marker type is known. + IMarker marker = ensureMarker(); + + // Read the extension registry and create applicable extensions. + List extensions = new ArrayList(4); + IExtensionPoint ep = Platform.getExtensionRegistry().getExtensionPoint(CDebugCorePlugin.getUniqueIdentifier(), CDebugCorePlugin.BREAKPOINT_EXTENSION_EXTENSION_POINT_ID); + IConfigurationElement[] elements = ep.getConfigurationElements(); + for (int i= 0; i < elements.length; i++) { + if ( elements[i].getName().equals(CDebugCorePlugin.BREAKPOINT_EXTENSION_ELEMENT) ) { + String elementDebugModelId = elements[i].getAttribute("debugModelId"); + String elementMarkerType = elements[i].getAttribute("markerType"); + if (elementDebugModelId == null) { + CDebugCorePlugin.log(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: markerType", null)); //$NON-NLS-1$ //$NON-NLS-2$ + } else if (elementMarkerType == null){ + CDebugCorePlugin.log(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: debugModelId", null)); //$NON-NLS-1$ //$NON-NLS-2$ + } else if ( debugModelId.equals(elementDebugModelId) && marker.isSubtypeOf(elementMarkerType)) { + String className = elements[i].getAttribute("class"); + if (className == null){ + CDebugCorePlugin.log(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " missing required attribute: className", null)); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + ICBreakpointExtension extension; + try { + extension = (ICBreakpointExtension)elements[i].createExecutableExtension("class"); + extension.initialize(this); + extensions.add(extension); + } catch (CoreException e) { + CDebugCorePlugin.log(new Status(IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), DebugPlugin.INTERNAL_ERROR, "Extension " + elements[i].getDeclaringExtension().getUniqueIdentifier() + " contains an invalid value for attribute: className", e)); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + } + } + } + fExtensions.put(debugModelId, extensions.toArray(new ICBreakpointExtension[extensions.size()])); + } + return (ICBreakpointExtension[])fExtensions.get(debugModelId); + } + + } diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpointFilterExtension.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpointFilterExtension.java new file mode 100644 index 00000000000..1dda58f61e1 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/breakpoints/CBreakpointFilterExtension.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.debug.internal.core.breakpoints; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; +import org.eclipse.cdt.debug.core.model.ICThread; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.model.IDebugTarget; + +/** + * + */ +public class CBreakpointFilterExtension implements ICBreakpointFilterExtension { + + public void initialize(ICBreakpoint breakpoint) { + } + + private Map fFilteredThreadsByTarget = new HashMap( 10 ); + + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getTargetFilters() + */ + public ICDebugTarget[] getTargetFilters() throws CoreException { + Set set = fFilteredThreadsByTarget.keySet(); + return (ICDebugTarget[])set.toArray( new ICDebugTarget[set.size()] ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#getThreadFilters(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public ICThread[] getThreadFilters( ICDebugTarget target ) throws CoreException { + Set set = (Set)fFilteredThreadsByTarget.get( target ); + return ( set != null ) ? (ICThread[])set.toArray( new ICThread[set.size()] ) : null; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public void removeTargetFilter( ICDebugTarget target ) throws CoreException { + if ( fFilteredThreadsByTarget.containsKey( target ) ) { + fFilteredThreadsByTarget.remove( target ); + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#removeThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) + */ + public void removeThreadFilters( ICThread[] threads ) throws CoreException { + if ( threads != null && threads.length > 0 ) { + IDebugTarget target = threads[0].getDebugTarget(); + if ( fFilteredThreadsByTarget.containsKey( target ) ) { + Set set = (Set)fFilteredThreadsByTarget.get( target ); + if ( set != null ) { + set.removeAll( Arrays.asList( threads ) ); + if ( set.isEmpty() ) { + fFilteredThreadsByTarget.remove( target ); + } + } + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setTargetFilter(org.eclipse.cdt.debug.core.model.ICDebugTarget) + */ + public void setTargetFilter( ICDebugTarget target ) throws CoreException { + fFilteredThreadsByTarget.put( target, null ); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.model.ICBreakpoint#setThreadFilters(org.eclipse.cdt.debug.core.model.ICThread[]) + */ + public void setThreadFilters( ICThread[] threads ) throws CoreException { + if ( threads != null && threads.length > 0 ) { + fFilteredThreadsByTarget.put( threads[0].getDebugTarget(), new HashSet( Arrays.asList( threads ) ) ); + } + } + +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 1ebe6501976..a61191e03c5 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1033,14 +1033,12 @@ - + - - + 1 ) { + action.setEnabled(false); return; } Object element = ss.getFirstElement(); if ( element instanceof ICBreakpoint ) { + action.setEnabled(true); setBreakpoint( (ICBreakpoint)element ); } } } - + protected IWorkbenchPart getActivePart() { return fPart; } protected ICBreakpoint getBreakpoint() { - return fBreakpoint; + return fContext; } + private ISelection getDebugContext() { + return DebugUITools.getDebugContextManager().getContextService(fPart.getSite().getWorkbenchWindow()).getActiveContext(); + } + protected void setBreakpoint( ICBreakpoint breakpoint ) { - fBreakpoint = breakpoint; + fContext = breakpoint; } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CBreakpointPropertiesRulerAction.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CBreakpointPropertiesRulerAction.java index fe82e41341e..e97be2c20b8 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CBreakpointPropertiesRulerAction.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/actions/CBreakpointPropertiesRulerAction.java @@ -11,9 +11,12 @@ *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.actions; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.internal.ui.CBreakpointContext; import org.eclipse.cdt.debug.internal.ui.ICDebugHelpContextIds; import org.eclipse.cdt.debug.internal.ui.IInternalCDebugUIConstants; import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.ui.DebugUITools; import org.eclipse.jface.text.source.IVerticalRulerInfo; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -28,7 +31,7 @@ import org.eclipse.ui.dialogs.PropertyDialogAction; */ public class CBreakpointPropertiesRulerAction extends AbstractBreakpointRulerAction { - private IBreakpoint fBreakpoint; + private Object fContext; /** * Creates the action to modify the breakpoint properties. @@ -44,14 +47,14 @@ public class CBreakpointPropertiesRulerAction extends AbstractBreakpointRulerAct * @see Action#run() */ public void run() { - if ( fBreakpoint != null ) { + if ( fContext != null ) { PropertyDialogAction action = new PropertyDialogAction( getTargetPart().getSite(), new ISelectionProvider() { public void addSelectionChangedListener( ISelectionChangedListener listener ) { } public ISelection getSelection() { - return new StructuredSelection( fBreakpoint ); + return new StructuredSelection( fContext ); } public void removeSelectionChangedListener( ISelectionChangedListener listener ) { @@ -69,7 +72,16 @@ public class CBreakpointPropertiesRulerAction extends AbstractBreakpointRulerAct * @see IUpdate#update() */ public void update() { - fBreakpoint = getBreakpoint(); - setEnabled( fBreakpoint != null ); + IBreakpoint breakpoint = getBreakpoint(); + if (breakpoint instanceof ICBreakpoint) { + fContext = new CBreakpointContext((ICBreakpoint)breakpoint, getDebugContext()); + } else { + fContext = breakpoint; + } + setEnabled( fContext != null ); + } + + private ISelection getDebugContext() { + return DebugUITools.getDebugContextManager().getContextService(getTargetPart().getSite().getWorkbenchWindow()).getActiveContext(); } } diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointFilteringPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointFilteringPage.java index 3e0de6b67b5..3015058afcc 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointFilteringPage.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointFilteringPage.java @@ -10,7 +10,10 @@ *******************************************************************************/ package org.eclipse.cdt.debug.internal.ui.propertypages; +import org.eclipse.cdt.debug.core.CDIDebugModel; import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; +import org.eclipse.core.runtime.CoreException; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -36,8 +39,19 @@ public class CBreakpointFilteringPage extends PropertyPage { return mainComposite; } - public ICBreakpoint getBreakpoint() { - return (ICBreakpoint)getElement(); + public ICBreakpoint getBreakpoint() { + return (ICBreakpoint)getElement().getAdapter(ICBreakpoint.class); + } + + public ICBreakpointFilterExtension getFilterExtension() { + ICBreakpoint bp = getBreakpoint(); + if (bp != null) { + try { + return (ICBreakpointFilterExtension)bp.getExtension( + CDIDebugModel.getPluginIdentifier(), ICBreakpointFilterExtension.class); + } catch (CoreException e) {} + } + return null; } protected void createThreadFilterEditor( Composite parent ) { diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java index 4ac5d5e41ed..d0e59c6a588 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/CBreakpointPropertyPage.java @@ -394,7 +394,7 @@ public class CBreakpointPropertyPage extends FieldEditorPreferencePage implement protected ICBreakpoint getBreakpoint() { IAdaptable element = getElement(); - return ( element instanceof ICBreakpoint ) ? (ICBreakpoint)element : null; + return ( element instanceof ICBreakpoint ) ? (ICBreakpoint)element : (ICBreakpoint)element.getAdapter(ICBreakpoint.class); } /* (non-Javadoc) diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/ThreadFilterEditor.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/ThreadFilterEditor.java index 8deec49fd7d..020f340a516 100644 --- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/ThreadFilterEditor.java +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/propertypages/ThreadFilterEditor.java @@ -12,7 +12,8 @@ package org.eclipse.cdt.debug.internal.ui.propertypages; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.debug.core.model.ICBreakpoint; + +import org.eclipse.cdt.debug.core.model.ICBreakpointFilterExtension; import org.eclipse.cdt.debug.core.model.ICDebugTarget; import org.eclipse.cdt.debug.core.model.ICThread; import org.eclipse.cdt.debug.ui.CDebugUIPlugin; @@ -282,11 +283,11 @@ public class ThreadFilterEditor { * checked. */ protected void setInitialCheckedState() { - ICBreakpoint breakpoint = fPage.getBreakpoint(); + ICBreakpointFilterExtension filterExtension = fPage.getFilterExtension(); try { - ICDebugTarget[] targets = breakpoint.getTargetFilters(); + ICDebugTarget[] targets = filterExtension.getTargetFilters(); for( int i = 0; i < targets.length; i++ ) { - ICThread[] filteredThreads = breakpoint.getThreadFilters( targets[i] ); + ICThread[] filteredThreads = filterExtension.getThreadFilters( targets[i] ); if ( filteredThreads != null ) { for ( int j = 0; j < filteredThreads.length; ++j ) fCheckHandler.checkThread( filteredThreads[j], true ); @@ -302,7 +303,7 @@ public class ThreadFilterEditor { } protected void doStore() { - ICBreakpoint breakpoint = fPage.getBreakpoint(); + ICBreakpointFilterExtension filterExtension = fPage.getFilterExtension(); IDebugTarget[] targets = getDebugTargets(); for ( int i = 0; i < targets.length; ++i ) { if ( !(targets[i] instanceof ICDebugTarget) ) @@ -311,16 +312,16 @@ public class ThreadFilterEditor { if ( getThreadViewer().getChecked( targets[i] ) ) { if ( getThreadViewer().getGrayed( targets[i] ) ) { ICThread[] threads = getTargetThreadFilters( (ICDebugTarget)targets[i] ); - breakpoint.setThreadFilters( threads ); + filterExtension.setThreadFilters( threads ); } else { - breakpoint.setTargetFilter( (ICDebugTarget)targets[i] ); + filterExtension.setTargetFilter( (ICDebugTarget)targets[i] ); } } else { - breakpoint.removeTargetFilter( (ICDebugTarget)targets[i] ); + filterExtension.removeTargetFilter( (ICDebugTarget)targets[i] ); } - DebugPlugin.getDefault().getBreakpointManager().fireBreakpointChanged( breakpoint ); + DebugPlugin.getDefault().getBreakpointManager().fireBreakpointChanged( fPage.getBreakpoint() ); } catch( CoreException e ) { CDebugUIPlugin.log( e );