diff options
20 files changed, 1048 insertions, 15 deletions
diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IGroupDebugContextsHandler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IGroupDebugContextsHandler.java new file mode 100644 index 00000000000..77cc075a8ba --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IGroupDebugContextsHandler.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.debug.core.commands.IDebugCommandHandler; + +/** + * Handler interface to perform grouping of debug contexts. + * + * @since 7.1 + */ +public interface IGroupDebugContextsHandler extends IDebugCommandHandler { + +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IUngroupDebugContextsHandler.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IUngroupDebugContextsHandler.java new file mode 100644 index 00000000000..d25b81ad6ec --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/model/IUngroupDebugContextsHandler.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.debug.core.model; + +import org.eclipse.debug.core.commands.IDebugCommandHandler; + +/** + * Handler interface to perform ungrouping of debug contexts. + * + * @since 7.1 + */ +public interface IUngroupDebugContextsHandler extends IDebugCommandHandler { + +} diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.properties b/debug/org.eclipse.cdt.debug.ui/plugin.properties index d10c308b012..719707c823f 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.properties +++ b/debug/org.eclipse.cdt.debug.ui/plugin.properties @@ -9,6 +9,7 @@ # QNX Software Systems - Initial API and implementation # IBM Corporation # Patrick Chuong (Texas Instruments) - Pin and Clone Supports (Bug 331781) +# Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) ############################################################################### pluginName=C/C++ Development Tools Debugger UI @@ -195,6 +196,15 @@ Uncall.name = Uncall Uncall.description = Perform Uncall Uncall.label = Uncall +# Debug View layout +DebugViewLayoutActionSet.label = Debug View Layout +DebugViewLayoutCategory.name = Debug View Layout Commands +DebugViewLayoutCategory.description = Set of commands for controlling the Debug View Layout +GroupDebugContexts.name = Group +GroupDebugContexts.description = Groups the selected debug contexts +UngroupDebugContexts.name = Ungroup +UngroupDebugContexts.description = Ungroups the selected debug contexts + # Menu for selecting breakpoint toggle type BreakpointTypes.label=B&reakpoint Types diff --git a/debug/org.eclipse.cdt.debug.ui/plugin.xml b/debug/org.eclipse.cdt.debug.ui/plugin.xml index 367410544cf..94262f51938 100644 --- a/debug/org.eclipse.cdt.debug.ui/plugin.xml +++ b/debug/org.eclipse.cdt.debug.ui/plugin.xml @@ -1818,6 +1818,11 @@ label="%TracepointActionSet.label" visible="false"> </actionSet> + <actionSet + id="org.eclipse.cdt.debug.ui.debugViewLayoutActionSet" + label="%DebugViewLayoutActionSet.label" + visible="false"> + </actionSet> </extension> <extension point="org.eclipse.ui.commands"> @@ -1897,6 +1902,23 @@ helpContextId="view_memory_context" name="%command.viewMemory.name"> </command> + <category + description="%DebugViewLayoutCategory.description" + id="org.eclipse.cdt.debug.ui.category.debugViewLayout" + name="%DebugViewLayoutCategory.name"> + </category> + <command + categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout" + description="%GroupDebugContexts.description" + id="org.eclipse.cdt.debug.ui.command.groupDebugContexts" + name="%GroupDebugContexts.name"> + </command> + <command + categoryId="org.eclipse.cdt.debug.ui.category.debugViewLayout" + description="%UngroupDebugContexts.description" + id="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts" + name="%UngroupDebugContexts.name"> + </command> </extension> <extension point="org.eclipse.ui.handlers"> @@ -1951,6 +1973,14 @@ </with> </activeWhen> </handler> + <handler + class="org.eclipse.cdt.debug.internal.ui.commands.GroupDebugContextsCommandHandler" + commandId="org.eclipse.cdt.debug.ui.command.groupDebugContexts"> + </handler> + <handler + class="org.eclipse.cdt.debug.internal.ui.commands.UngroupDebugContextsCommandHandler" + commandId="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts"> + </handler> </extension> <extension point="org.eclipse.core.expressions.definitions"> @@ -2004,6 +2034,18 @@ </iterate> </with> </definition> + <definition + id="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive"> + <with + variable="activeContexts"> + <iterate + operator="or"> + <equals + value="org.eclipse.cdt.debug.ui.debugViewLayoutActionSet"> + </equals> + </iterate> + </with> + </definition> </extension> <extension point="org.eclipse.ui.bindings"> @@ -2297,6 +2339,53 @@ </visibleWhen> </command> </menuContribution> + <menuContribution + locationURI="popup:org.eclipse.debug.ui.DebugView?after=emptyStepGroup"> + <command + commandId="org.eclipse.cdt.debug.ui.command.groupDebugContexts" + label="%GroupDebugContexts.name"> + <visibleWhen + checkEnabled="false"> + <and> + <reference + definitionId="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive"> + </reference> + <with + variable="debugContext"> + <iterate + ifEmpty="false" + operator="and"> + <test + property="org.eclipse.cdt.debug.ui.isGroupDebugContextsVisible"> + </test> + </iterate> + </with> + </and> + </visibleWhen> + </command> + <command + commandId="org.eclipse.cdt.debug.ui.command.ungroupDebugContexts" + label="%UngroupDebugContexts.name"> + <visibleWhen + checkEnabled="false"> + <and> + <reference + definitionId="org.eclipse.cdt.debug.ui.testDebugViewLayoutActionSetActive"> + </reference> + <with + variable="debugContext"> + <iterate + ifEmpty="false" + operator="and"> + <test + property="org.eclipse.cdt.debug.ui.isUngroupDebugContextsVisible"> + </test> + </iterate> + </with> + </and> + </visibleWhen> + </command> + </menuContribution> </extension> <!-- Cast to Type / Display as Array --> diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/GroupDebugContextsCommandHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/GroupDebugContextsCommandHandler.java new file mode 100644 index 00000000000..f9d640638bf --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/GroupDebugContextsCommandHandler.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.commands; + +import org.eclipse.cdt.debug.core.model.IGroupDebugContextsHandler; +import org.eclipse.debug.ui.actions.DebugCommandHandler; + +/** + * Command handler to trigger grouping of debug contexts operation. + * + * @since 7.1 + */ +public class GroupDebugContextsCommandHandler extends DebugCommandHandler { + + @Override + protected Class<?> getCommandType() { + return IGroupDebugContextsHandler.class; + } +} diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/UngroupDebugContextsCommandHandler.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/UngroupDebugContextsCommandHandler.java new file mode 100644 index 00000000000..dd39c1b9adb --- /dev/null +++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/commands/UngroupDebugContextsCommandHandler.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.debug.internal.ui.commands; + +import org.eclipse.cdt.debug.core.model.IUngroupDebugContextsHandler; +import org.eclipse.debug.ui.actions.DebugCommandHandler; + +/** + * Command handler to trigger ungrouping of debug contexts operation. + * + * @since 7.1 + */ +public class UngroupDebugContextsCommandHandler extends DebugCommandHandler { + + @Override + protected Class<?> getCommandType() { + return IUngroupDebugContextsHandler.class; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF index 8b826ad585d..7f877def795 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf.ui/META-INF/MANIFEST.MF @@ -22,6 +22,8 @@ Require-Bundle: org.eclipse.ui;bundle-version="3.5.0", Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.dsf.debug.internal.ui;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.actions;x-internal:=true, + org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout;x-internal:=true, + org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions, org.eclipse.cdt.dsf.debug.internal.ui.disassembly;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.disassembly.actions;x-internal:=true, org.eclipse.cdt.dsf.debug.internal.ui.disassembly.model;x-internal:=true, diff --git a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml index acaf81f9678..2f4990f3a05 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/plugin.xml +++ b/dsf/org.eclipse.cdt.dsf.ui/plugin.xml @@ -450,8 +450,14 @@ properties="areNumberFormatsSupported,isNumberFormatAvailable,isNumberFormatActive" type="org.eclipse.debug.ui.IDebugView"> </propertyTester> + <propertyTester + class="org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.DebugViewLayoutTester" + id="org.eclipse.cdt.dsf.ui.debug.view.layout.DebugViewLayoutTester" + namespace="org.eclipse.cdt.debug.ui" + properties="isGroupDebugContextsVisible,isUngroupDebugContextsVisible" + type="org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext"> + </propertyTester> </extension> - <extension point="org.eclipse.debug.ui.detailPaneFactories"> <detailFactories @@ -790,4 +796,5 @@ </editor> </extension> + </plugin> diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/DebugViewLayoutTester.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/DebugViewLayoutTester.java new file mode 100644 index 00000000000..2ef82d481d6 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/DebugViewLayoutTester.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout; + +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.core.expressions.PropertyTester; + +/** + * Property tester for debug view related commands - group, ungroup, hide, etc. + * + * @since 2.2 + */ + +public class DebugViewLayoutTester extends PropertyTester{ + + public DebugViewLayoutTester() { + } + + protected static final String IS_GROUP_VISIBLE = "isGroupDebugContextsVisible"; //$NON-NLS-1$ + protected static final String IS_UNGROUP_VISIBLE = "isUngroupDebugContextsVisible"; //$NON-NLS-1$ + + public boolean test(Object receiver, String property, Object[] args, Object expectedValue) { + + if( IS_GROUP_VISIBLE.equals(property) || IS_UNGROUP_VISIBLE.equals(property)) { + if (receiver instanceof IDMVMContext) { + return test((IDMVMContext)receiver); + } + } + return false; + } + + private boolean test(IDMVMContext dmContext) { + String sessionId = dmContext.getDMContext().getSessionId(); + return DsfSession.isSessionActive(sessionId); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfDebugViewLayoutCommand.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfDebugViewLayoutCommand.java new file mode 100644 index 00000000000..354deb80239 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfDebugViewLayoutCommand.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ + +package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions; + +import java.util.HashSet; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.DsfExecutor; +import org.eclipse.cdt.dsf.concurrent.DsfRunnable; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.internal.ui.DsfUIPlugin; +import org.eclipse.cdt.dsf.service.DsfServicesTracker; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.debug.core.commands.IDebugCommandHandler; +import org.eclipse.debug.core.commands.IDebugCommandRequest; +import org.eclipse.debug.core.commands.IEnabledStateRequest; + +/** + * @since 2.2 + */ +@SuppressWarnings("restriction") +public abstract class DsfDebugViewLayoutCommand implements IDebugCommandHandler{ + + protected final DsfExecutor fExecutor; + protected final DsfServicesTracker fTracker; + protected static IExecutionDMContext[] EMPTY_ARRAY = new IExecutionDMContext[0]; + + public DsfDebugViewLayoutCommand(DsfSession session) { + fExecutor = session.getExecutor(); + fTracker = new DsfServicesTracker(DsfUIPlugin.getBundleContext(), session.getId()); + } + + public void dispose() { + fTracker.dispose(); + } + + /** + * + * @param request + * @return set of IExecutionDMContext if: + * - all elements are from a DSF session. + * - all elements are from the same DSF session. + */ + protected IExecutionDMContext[] getDMContexts( IDebugCommandRequest request) { + + HashSet<IExecutionDMContext> ret = new HashSet<IExecutionDMContext>(); + String sessionId = null; + + for( Object obj : request.getElements()) { + if(!( obj instanceof IDMVMContext )) + return EMPTY_ARRAY; + + IDMContext dmContext = ((IDMVMContext)obj).getDMContext(); + IExecutionDMContext exeContext = DMContexts.getAncestorOfType(dmContext, IExecutionDMContext.class); + + if( exeContext == null) + return EMPTY_ARRAY; + + // make sure all elements are from the same DSF session. + if( sessionId == null) { + sessionId = dmContext.getSessionId(); + } + else { + if( !sessionId.equals(dmContext.getSessionId())) + return EMPTY_ARRAY; + } + + ret.add(exeContext); + } + return ret.toArray(new IExecutionDMContext[0]); + } + + public void canExecute(final IEnabledStateRequest request) { + final IExecutionDMContext[] executionContexts = getDMContexts( request); + if( executionContexts.length > 0 && !fExecutor.isTerminated()) { + fExecutor.submit(new DsfRunnable() { + public void run() { + IExecutionContextTranslator translator = fTracker.getService(IExecutionContextTranslator.class); + if( translator != null) { + canExecuteOnDsfThread(translator, executionContexts, + new DataRequestMonitor<Boolean>(fExecutor, null) { + @Override + protected void handleCompleted() { + boolean canExecute = isSuccess() && getData(); + request.setEnabled(canExecute); + request.done(); + } + }); + + } else { + request.setEnabled(false); + request.done(); + } + } + }); + } + else { + request.setEnabled(false); + request.done(); + } + } + + public boolean execute(final IDebugCommandRequest request) { + final IExecutionDMContext[] executionContexts = getDMContexts( request); + if( executionContexts.length > 0 && !fExecutor.isTerminated()) { + fExecutor.submit(new DsfRunnable() { + public void run() { + IExecutionContextTranslator translator = fTracker.getService(IExecutionContextTranslator.class); + if( translator != null) { + executeOnDsfThread(translator, executionContexts, + new RequestMonitor(fExecutor, null) { + @Override + protected void handleCompleted() { + request.done(); + } + }); + } + else + request.done(); + } + }); + return false; + } + request.done(); + return true; + } + + abstract void executeOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor); + abstract void canExecuteOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfGroupDebugContextsCommand.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfGroupDebugContextsCommand.java new file mode 100644 index 00000000000..0826fd715fa --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfGroupDebugContextsCommand.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandHandler; + +/** + * @since 2.2 + */ +@SuppressWarnings("restriction") +public class DsfGroupDebugContextsCommand extends DsfDebugViewLayoutCommand implements IDebugCommandHandler{ + + @Override + void executeOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor) { + translator.group(contexts, requestMonitor); + } + + @Override + void canExecuteOnDsfThread( IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { + translator.canGroup(contexts, rm); + } + + public DsfGroupDebugContextsCommand(DsfSession session) { + super( session); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfUngroupDebugContextsCommand.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfUngroupDebugContextsCommand.java new file mode 100644 index 00000000000..ac68fe9b8b2 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/internal/ui/debugview/layout/actions/DsfUngroupDebugContextsCommand.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 336876) +********************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.ui.debugview.layout.actions; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.debug.core.commands.IDebugCommandHandler; + +/** + * @since 2.2 + */ +@SuppressWarnings("restriction") +public class DsfUngroupDebugContextsCommand extends DsfDebugViewLayoutCommand implements IDebugCommandHandler{ + + public DsfUngroupDebugContextsCommand(DsfSession session) { + super( session); + } + + @Override + void executeOnDsfThread(IExecutionContextTranslator translator, IExecutionDMContext[] contexts, RequestMonitor requestMonitor) { + translator.ungroup(contexts, requestMonitor); + } + + @Override + void canExecuteOnDsfThread(IExecutionContextTranslator translator, IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm) { + translator.canUngroup(contexts, rm); + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java index 5631f20b824..df83b1169b0 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractContainerVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2011 Wind River Systems, Inc. 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 @@ -8,6 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation * Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566) + * Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch; @@ -41,7 +42,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate; import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider; @@ -65,7 +65,7 @@ import org.eclipse.debug.ui.IDebugUIConstants; * * @since 1.1 */ -public abstract class AbstractContainerVMNode extends AbstractDMVMNode +public abstract class AbstractContainerVMNode extends AbstractExecutionContextVMNode implements IElementLabelProvider, IElementPropertiesProvider { /** diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractExecutionContextVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractExecutionContextVMNode.java new file mode 100644 index 00000000000..245850407f9 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractExecutionContextVMNode.java @@ -0,0 +1,344 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 240208) +********************************************************************************/ +package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch; + +import java.util.ArrayList; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.datamodel.DMContexts; +import org.eclipse.cdt.dsf.datamodel.IDMContext; +import org.eclipse.cdt.dsf.datamodel.IDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerSuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent; +import org.eclipse.cdt.dsf.debug.service.IRunControl.ISuspendedDMEvent; +import org.eclipse.cdt.dsf.debug.ui.viewmodel.SteppingController.SteppingTimedOutEvent; +import org.eclipse.cdt.dsf.service.DsfSession; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext; +import org.eclipse.cdt.dsf.ui.viewmodel.IVMNode; +import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; + +/** + * This class is a base class of AbstractThreadVMNode and AbstractContainerVMNode. + * It contains common functionality between these classes. + * + * The main reason this class is introduce is to allow the debug view to + * show multiple levels of execution containers and properly handle the delta generation. + * + * Longer term we would like to merge the classes AbstractContainerVMNode and + * AbstractThreadVMNode. That will make the implementation of both classes + * more generic and robust in the case of recursive containers. + * + * Having this class as a base for both AbstractContainerVMNode and + * AbstractThreadVMNode enables us to merge them in the future. + * + * Originally DefaultVMModelProxyStrategy didn't accept recursive container for + * generating deltas, even though they are accepted and supported by + * AbstractDMVMProvider for viewing. + * The approach I took to support recursive container in delta generation is to have + * the VMNodes to generate level by level its deltas instead of one the whole delta at once. + * That required changes in identifying which is the correct context for each of the events. + * + * See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=240208 + * + * @since 2.2 + * @experimental + */ +public abstract class AbstractExecutionContextVMNode extends AbstractDMVMNode +{ + /** + * List that keeps track of which events are considered leave events for + * delta creation. + */ + protected ArrayList<Class<?>> leafEventTypes = new ArrayList<Class<?>>(); + + /** + * List that keeps track of which events are considered container events for + * delta creation. + */ + protected ArrayList<Class<?>> containerEventTypes = new ArrayList<Class<?>>(); + + /** + * Constructor. + * Pass the parameter to the base class's constructor. + * + * @param session + * @param dmcClassType + * + * @see #setChildNodes(IVMNode[]) + */ + public AbstractExecutionContextVMNode(AbstractDMVMProvider provider, + DsfSession session, Class<? extends IDMContext> dmcClassType) { + super(provider, session, dmcClassType); + } + + /** + * Adds the events that common DSF classes relay on. + */ + protected void addCommonEventTypes() { + + // non container events. + addEventType(ISuspendedDMEvent.class,false); + addEventType(IResumedDMEvent.class, false); + addEventType(FullStackRefreshEvent.class, false); + addEventType(SteppingTimedOutEvent.class, false); + addEventType(ExpandStackEvent.class, false); + + // container events. + addEventType(IContainerSuspendedDMEvent.class,true); + addEventType(IContainerResumedDMEvent.class, true); + } + + /** + * When DSF debugger define custom events for which the containers and threads + * nodes needs to be update they can need to register these events using this + * function, so the proper recursive deltas are being created. + * + * @param eventClass + */ + protected void addEventType( Class<? extends IDMEvent<?>> eventClass, boolean containerEvent) + { + if( containerEvent) + containerEventTypes.add( eventClass); + else + leafEventTypes.add( eventClass); + } + + /** + * If DSF debuggers overrides the behavior of the AbstractThreadVMNode + * or AbstractContainerVMNode, some event are no longer needed the derived + * VMNdoe can call this method to remove some events. + * + * @param eventClass + * @param containerEvent + */ + protected void removeEventType( Class<?> eventClass, boolean containerEvent) { + if( containerEvent) + containerEventTypes.remove( eventClass); + else + leafEventTypes.remove( eventClass); + } + + + /** + * When we support recursive containers we want to make sure the immediate parent is returned only. + * + * @param parentDelta + * @param e + * @param rm - request monitor + * @return true if the context is set by the method. + */ + protected boolean getContextsForRecursiveVMNode(VMDelta parentDelta, Object e, final DataRequestMonitor<IVMContext[]> rm) { + + IExecutionDMContext leafContext = null; + if( isExecutionContainerEvent(e)) { + leafContext = getLeafContextForContainerEvent( e); + } + else if( isExecutionLeafEvent(e)) { + leafContext = getLeafContextForLeafEvent( e); + } + if( leafContext != null) { + setImmediateParentAsContexts(leafContext,parentDelta,rm); + return true; + } + return false; + } + + /** + * Make sure we build the delta for the recursive containers one level at a time. + * + * @param e - the events. + * @param parentDelta + * @param nodeOffset + * @param requestMonitor + * @return true if the delta is built by this method. + */ + protected boolean buildDeltaForRecursiveVMNode(Object e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + + IExecutionDMContext leafContext = null; + if( isExecutionContainerEvent(e)) { + leafContext = getLeafContextForContainerEvent( e); + } + else if( isExecutionLeafEvent(e)) { + leafContext = getLeafContextForLeafEvent( e); + } + if( leafContext != null) { + addOneLevelToDelta( leafContext, parentDelta, requestMonitor); + return true; + } + return false; + } + + /** + * When the deltas are generated one level at a time we needs to distinguish + * between container and regular event to return the proper context for the event. + * + * @param event + * @return + */ + protected IExecutionDMContext getLeafContextForContainerEvent( Object event) { + + IExecutionDMContext leafEC = null; + IExecutionDMContext[] triggeringContext = null; + + if( isExecutionContainerEvent(event)) { + if( event instanceof IContainerSuspendedDMEvent) { + IContainerSuspendedDMEvent typedEvent = (IContainerSuspendedDMEvent)event; + triggeringContext = typedEvent.getTriggeringContexts(); + } + if( event instanceof IContainerResumedDMEvent) { + IContainerResumedDMEvent typedEvent = (IContainerResumedDMEvent)event; + triggeringContext = typedEvent.getTriggeringContexts(); + } + } + + if( triggeringContext != null && triggeringContext.length > 0){ + leafEC = triggeringContext[0]; + } + + return leafEC; + } + + /** + * When the deltas are generated one level at a time we needs to distinguish + * between container and regular event to return the proper context for the event. + * + * @param event + * @return + */ + protected IExecutionDMContext getLeafContextForLeafEvent( Object event) { + + IExecutionDMContext leafEC = null; + + if( event instanceof IDMEvent<?>) + if( isExecutionLeafEvent( event)) { + IDMEvent<?> typedEvent = (IDMEvent<?>)event; + IDMContext dmContext = typedEvent.getDMContext(); + if( dmContext instanceof IExecutionDMContext) + leafEC = (IExecutionDMContext)dmContext; + } + + return leafEC; + } + + /** + * Considers the parent delta when we construct the next level. + * + * @param leafContext + * @param parentDelta + * @param requestMonitor + */ + protected void addOneLevelToDelta( IExecutionDMContext leafContext, VMDelta parentDelta, RequestMonitor requestMonitor) { + assert leafContext != null; + if( parentDelta.getElement() instanceof ILaunch) { + IContainerDMContext topContainer = + DMContexts.getTopMostAncestorOfType( leafContext, IContainerDMContext.class); + + // It is possible for a thread node to be an immediate child of a launch node + // with no container node in between. + if( topContainer != null) + parentDelta.addNode(createVMContext(topContainer), 0, IModelDelta.NO_CHANGE); + } + else if( parentDelta.getElement() instanceof IDMVMContext) { + IDMVMContext vmContext = (IDMVMContext)parentDelta.getElement(); + IDMContext dmContext = vmContext.getDMContext(); + IExecutionDMContext current = DMContexts.getParentOfType(leafContext, IContainerDMContext.class); + while( current != null) { + IContainerDMContext parent = DMContexts.getParentOfType(current, IContainerDMContext.class); + if( dmContext.equals(parent)) { + parentDelta.addNode(createVMContext(current), 0, IModelDelta.NO_CHANGE); + break; + } + current = parent; + } + } + requestMonitor.done(); + } + + /** + * Based on the event (container or not) set the proper context that is the immediate + * parent one level at a time. + * + * @param leafContext + * @param parentDelta + * @param rm + */ + protected void setImmediateParentAsContexts( IExecutionDMContext leafContext, + VMDelta parentDelta, DataRequestMonitor<IVMContext[]> rm){ + + assert leafContext != null; + IVMContext[] all = null; + if( parentDelta.getElement() instanceof ILaunch) { + IContainerDMContext topContainer = + DMContexts.getTopMostAncestorOfType( leafContext, IContainerDMContext.class); + if( topContainer != null) { + all = new IVMContext[] { createVMContext(topContainer) }; + } + else { + // the thread is directly a child node of the launch node (no container in the middle). + all = new IVMContext[] { createVMContext(leafContext) }; + } + } + else if( parentDelta.getElement() instanceof IDMVMContext) { + IDMVMContext vmContext = (IDMVMContext)parentDelta.getElement(); + IDMContext dmContext = vmContext.getDMContext(); + IExecutionDMContext current = leafContext; + while( current != null) { + IContainerDMContext parent = DMContexts.getParentOfType(current, IContainerDMContext.class); + if( dmContext.equals(parent)) { + all = new IVMContext[] { createVMContext(current)}; + break; + } + current = parent; + } + } + if( all == null) + all = new IVMContext[0]; + rm.setData( all ); + rm.done(); + } + + /** + * Returns whether the event should be considered a container event or not. + * + * @param event + * @return + */ + protected boolean isExecutionContainerEvent( Object event) { + if( event != null) + for( Class<?> clazz : containerEventTypes) + if( clazz.isAssignableFrom(event.getClass())) + return true; + return false; + } + + /** + * Returns whether the event should be use to generate delta for each of the levels. + * + * @param event + * @return + */ + protected boolean isExecutionLeafEvent( Object event) { + if( event != null) + for( Class<?> clazz : leafEventTypes) + if( clazz.isAssignableFrom(event.getClass())) + return true; + return false; + } +} diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractThreadVMNode.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractThreadVMNode.java index b6c244b866f..36e6e78bbfb 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractThreadVMNode.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/debug/ui/viewmodel/launch/AbstractThreadVMNode.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems and others. + * Copyright (c) 2006, 2011 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 @@ -9,6 +9,7 @@ * Wind River Systems - initial API and implementation * Ericsson - Modified for multi threaded functionality * Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566) + * Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208) *******************************************************************************/ package org.eclipse.cdt.dsf.debug.ui.viewmodel.launch; @@ -42,7 +43,6 @@ import org.eclipse.cdt.dsf.ui.viewmodel.IVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.ModelProxyInstalledEvent; import org.eclipse.cdt.dsf.ui.viewmodel.VMChildrenUpdate; import org.eclipse.cdt.dsf.ui.viewmodel.VMDelta; -import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMNode; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.AbstractDMVMProvider; import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.cdt.dsf.ui.viewmodel.properties.IElementPropertiesProvider; @@ -68,7 +68,7 @@ import org.eclipse.debug.ui.IDebugUIConstants; * * @since 1.1 */ -public abstract class AbstractThreadVMNode extends AbstractDMVMNode +public abstract class AbstractThreadVMNode extends AbstractExecutionContextVMNode implements IElementLabelProvider, IElementPropertiesProvider { /** diff --git a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java index ffc5edee006..9e6e883a209 100644 --- a/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java +++ b/dsf/org.eclipse.cdt.dsf.ui/src/org/eclipse/cdt/dsf/ui/viewmodel/DefaultVMModelProxyStrategy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2010 IBM Corporation and others. + * Copyright (c) 2005, 2011 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 @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Wind River Systems - adapted to use with DSF + * Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208) *******************************************************************************/ package org.eclipse.cdt.dsf.ui.viewmodel; @@ -21,6 +22,7 @@ import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.DsfRunnable; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.ui.viewmodel.datamodel.IDMVMContext; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.SafeRunner; @@ -63,6 +65,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { private boolean fDisposed = false; private ListenerList fListeners = new ListenerList(); private IDoubleClickListener fDoubleClickListener; + private boolean fAllowRecursiveVMNodes = false; /** * Creates this model proxy strategy for the given provider. @@ -337,7 +340,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { // of the viewer. Get the root node of the chain--i.e., // the delta for the root element of the entire viewer. final IModelDelta viewRootDelta = getRootDelta(getData()); - + // Find the child nodes that (may) have deltas for the given event. final Map<IVMNode,Integer> childNodesWithDeltaFlags = getChildNodesWithDeltaFlags(rootNode, getData(), event); @@ -695,8 +698,36 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { delta.setChildCount(getData().get(null)); for (final IVMNode childNode : childNodes.keySet()) { - // Avoid descending into recursive node hierarchy's when calculating the delta. - if (node.equals(childNode)) continue; + + if (node.equals(childNode)) { + + // Avoid descending into recursive node hierarchy's when calculating the delta. + // if recursive nodes are not allowed. + if( !allowRecursiveVMNodes()) + continue; + + // get into recursion to build the delta only if the recursive context is added. + // + // We user current assumption that recursive container can be added as first children + // if the list of VMNodes. If we decide to make the patch more generic ( allow recursive + // node to be at different index) we need to remove this simplification. + // + if( isDeltaElementOfType(delta, childNode)) { + childNode.buildDelta( + event, delta, 0, + new RequestMonitor(getVMProvider().getExecutor(), multiRm) { + @Override + protected void handleSuccess() { + buildChildDeltas( + childNode, event, delta, 0, + new RequestMonitor(getVMProvider().getExecutor(), multiRm) ); + } + }); + multiRmCount++; + } + + continue; + } final int nodeOffset = getData().get(childNode); childNode.buildDelta( @@ -793,7 +824,7 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { protected Map<IVMNode, Integer> getChildNodesWithDeltaFlags(IVMNode node, ModelDelta parentDelta, Object e) { Map<IVMNode, Integer> nodes = new HashMap<IVMNode, Integer>(); for (final IVMNode childNode : getVMProvider().getChildVMNodes(node)) { - if (!childNode.equals(node)) { + if (!childNode.equals(node) || allowRecursiveVMNodes()) { int delta = getDeltaFlags(childNode, parentDelta, e); if (delta != IModelDelta.NO_CHANGE) { nodes.put(childNode, delta); @@ -803,5 +834,57 @@ public class DefaultVMModelProxyStrategy implements IVMModelProxy { return nodes; } + /** + * Returns whether DefaultVMModelProxyStrategy allows to handles recursive VMNdoes hierarchy. + * + * @see setAllowRecursiveVMNodes() + * @return true if this DefaultVMModelProxyStrategy allows recursive containers. + */ + public boolean allowRecursiveVMNodes() { + return fAllowRecursiveVMNodes; + } + + /** + * Allow DefaultVMModelProxyStrategy to handles recursive VMNdoes hierarchy. + * + * For example if the client wants the debug view to display container nodes that + * have containers this flag has to be set. + * + * Launch1 + * Container-1 + * Container-1.1 + * Thread-1 + * Container-1.1.1 + * Thread-2 + * Thread-2 + * + * This will allow the client to setup a VMNode to be in the list of its children. + * addChildNodes(containerNode, new IVMNode[] { containerNode, threadsNode }); + * + * The client also need to make sure the recursive VMNodes and their immediate children: + * 1. Handles buildDelta() by building one level at a time by examining the delta passed as parameter. + * 2. Returns the correct level container inside getContextsForEvent() based on the delta passed. + * + * See org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.ContainerVMNode for sample implementation. + * + * @param allow - whether to allow or not recursive containment of VMNodes. + */ + public void setAllowRecursiveVMNodes( boolean allow) { + fAllowRecursiveVMNodes = allow; + } + /** + * Compares if the VMNode of element of the provided delta is the same as the provided IVMNode. + * + * @param delta - delta for which to compare the IDMVMContext + * @param node - the IVMNode we want to compare to. + * @return if the VMNode of element of the provided delta is the same as the provided IVMNode. + */ + protected boolean isDeltaElementOfType( VMDelta delta, IVMNode node) { + if( delta.getElement() instanceof IDMVMContext) { + IDMVMContext dmvmContext = (IDMVMContext)delta.getElement(); + return dmvmContext.getVMNode().equals(node); + } + return false; + } } diff --git a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF index 4f59e0c546c..c9121699acd 100644 --- a/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF +++ b/dsf/org.eclipse.cdt.dsf/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.cdt.dsf.concurrent, org.eclipse.cdt.dsf.datamodel, org.eclipse.cdt.dsf.debug.internal.provisional.model;x-friends:="org.eclipse.cdt.dsf.ui", + org.eclipse.cdt.dsf.debug.internal.provisional.service;x-internal:=true, org.eclipse.cdt.dsf.debug.model, org.eclipse.cdt.dsf.debug.service, org.eclipse.cdt.dsf.debug.service.command, diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/datamodel/DMContexts.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/datamodel/DMContexts.java index 1692aa31e5c..6cb7c8850a8 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/datamodel/DMContexts.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/datamodel/DMContexts.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2009 Wind River Systems and others. + * Copyright (c) 2006, 2011 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 @@ -8,6 +8,7 @@ * Contributors: * Wind River Systems - initial API and implementation * Ericsson - Modified for additional features in DSF Reference implementation + * Dobrin Alexiev (Texas Instruments) - added helpers for recursive data model contexts (bug 240208) *******************************************************************************/ package org.eclipse.cdt.dsf.datamodel; @@ -74,6 +75,63 @@ public class DMContexts { } /** + * Finds the top most ancestor of the specified type. + * It assumes only one immediate parent of the give type exists. + * The search is done until there is no more immediate parents of the given type. + * The method returns the last one found. + * + * @param <V> + * @param ctx DMC to search. + * @param ancestorType Class type of the desired DMC ancestor. + * @return Returns the ancestor if found, null otherwise. + * @since 2.2 + */ + @ThreadSafe + @SuppressWarnings("unchecked") + public static <V extends IDMContext> V getTopMostAncestorOfType(IDMContext ctx, Class<V> ancestorType) { + if(ctx == null) + return null; + + V topMostAncestor = null; + boolean hasAncestorOfType = false; + IDMContext current = ctx; + do { + hasAncestorOfType = false; + IDMContext[] parents = current.getParents(); + for( IDMContext parent : parents) { + if (ancestorType.isAssignableFrom(parent.getClass())) { + hasAncestorOfType = true; + topMostAncestor = (V) parent; + current = parent; + } + } + + } while( hasAncestorOfType); + return topMostAncestor; + } + + /** + * Finds the immediate parent of the specified type if exists. + * + * @param ctx DMC to search. + * @param ancestorType Class type of the desired DMC ancestor. + * @return Returns the ancestor if found, null otherwise. + * @since 2.2 + */ + @ThreadSafe + @SuppressWarnings("unchecked") + public static <V extends IDMContext> V getParentOfType(IDMContext ctx, Class<V> ancestorType) { + if(ctx == null) + return null; + + for( IDMContext parent : ctx.getParents()) + if (ancestorType.isAssignableFrom(parent.getClass())) + return (V)parent; + + return null; + } + + /** * Finds all data model contexts of given type among ancestors of the * specified context. Ancestors are returned in order of closest to farthest, * in terms of depth. diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/service/IExecutionContextTranslator.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/service/IExecutionContextTranslator.java new file mode 100644 index 00000000000..4fa967ed524 --- /dev/null +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/internal/provisional/service/IExecutionContextTranslator.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 Texas Instruments, Inc. 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: + * Dobrin Alexiev (Texas Instruments) - initial API and implementation (bug 240208) +********************************************************************************/ +package org.eclipse.cdt.dsf.debug.internal.provisional.service; + +import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; +import org.eclipse.cdt.dsf.concurrent.RequestMonitor; +import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.cdt.dsf.service.IDsfService; + +/** + * EXPERIMENTAL. This class or interface has been added as part + * of a work in progress. There is no guarantee that this API will work or that + * it will remain the same. + * + * Interface for translating one model of execution context hierarchy to another. + * As the grouping feature is added incrementally this interface will be defined properly. + * + * The reason this interface is proposed at the DSF level is to accommodate requirements from + * multiple DSF debuggers. + * + * @since 2.2 + * @experimental + */ +public interface IExecutionContextTranslator extends IDsfService { + + /** + * returns true if all DM contexts can be grouped into one container. + * + * @param context + * @param rm + */ + void canGroup(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + + /** + * returns true if all DM contexts can be ungrouped. + * + * @param context + * @param rm + */ + void canUngroup(IExecutionDMContext[] contexts, DataRequestMonitor<Boolean> rm); + + /** + * Groups the specified execution contexts. + * + * @param context + * @param requestMonitor + */ + void group(IExecutionDMContext[] contexts, RequestMonitor requestMonitor); + + /** + * Ungroups the specified execution contexts. + * + * @param context + * @param requestMonitor + */ + void ungroup(IExecutionDMContext[] contexts, RequestMonitor requestMonitor); +} diff --git a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java index 6ed919d0250..d8e7487f425 100644 --- a/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java +++ b/dsf/org.eclipse.cdt.dsf/src/org/eclipse/cdt/dsf/debug/service/AbstractDsfDebugServicesFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Ericsson and others. + * Copyright (c) 2008, 2011 Ericsson 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 @@ -7,9 +7,11 @@ * * Contributors: * Ericsson - initial API and implementation - *******************************************************************************/ + * Dobrin Alexiev (Texas Instruments) - user groups support (bug 240208) +********************************************************************************/ package org.eclipse.cdt.dsf.debug.service; +import org.eclipse.cdt.dsf.debug.internal.provisional.service.IExecutionContextTranslator; import org.eclipse.cdt.dsf.debug.service.command.ICommandControl; import org.eclipse.cdt.dsf.service.DsfSession; @@ -48,6 +50,8 @@ public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServic return (V)createStackService(session); } else if (ISymbols.class.isAssignableFrom(clazz)) { return (V)createSymbolsService(session); + } else if (IExecutionContextTranslator.class.isAssignableFrom(clazz)) { + return (V)createExecutionContextTranslator(session); } return null; @@ -66,5 +70,10 @@ public abstract class AbstractDsfDebugServicesFactory implements IDsfDebugServic protected ISignals createSignalsService(DsfSession session) { return null; } protected IStack createStackService(DsfSession session) { return null; } protected ISymbols createSymbolsService(DsfSession session) { return null; } + + /** + * @since 2.2 + */ + protected IExecutionContextTranslator createExecutionContextTranslator( DsfSession session) { return null; } } |