diff options
Diffstat (limited to 'plugins/com.windriver.tcf.dsf.ui')
15 files changed, 1006 insertions, 0 deletions
diff --git a/plugins/com.windriver.tcf.dsf.ui/.classpath b/plugins/com.windriver.tcf.dsf.ui/.classpath new file mode 100644 index 000000000..751c8f2e5 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/plugins/com.windriver.tcf.dsf.ui/.project b/plugins/com.windriver.tcf.dsf.ui/.project new file mode 100644 index 000000000..77c9739b6 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>com.windriver.tcf.dsf.ui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/plugins/com.windriver.tcf.dsf.ui/META-INF/MANIFEST.MF b/plugins/com.windriver.tcf.dsf.ui/META-INF/MANIFEST.MF new file mode 100644 index 000000000..a4b898b02 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/META-INF/MANIFEST.MF @@ -0,0 +1,20 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: %pluginName +Bundle-SymbolicName: com.windriver.tcf.dsf.ui;singleton:=true +Bundle-Version: 0.1.0 +Bundle-Activator: com.windriver.tcf.dsf.ui.Activator +Bundle-Vendor: %providerName +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + org.eclipse.dd.dsf.debug, + org.eclipse.dd.dsf.debug.ui, + org.eclipse.dd.dsf, + org.eclipse.dd.dsf.ui, + org.eclipse.debug.ui, + com.windriver.tcf.api, + com.windriver.debug.tcf.core, + com.windriver.debug.tcf.ui, + com.windriver.tcf.dsf.core +Eclipse-LazyStart: true +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/plugins/com.windriver.tcf.dsf.ui/about.html b/plugins/com.windriver.tcf.dsf.ui/about.html new file mode 100755 index 000000000..6c5b3615b --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/about.html @@ -0,0 +1,28 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> +<title>About</title> +</head> +<body lang="EN-US"> +<h2>About This Content</h2> + +<p>January 10, 2008</p> +<h3>License</h3> + +<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise +indicated below, the Content is provided to you under the terms and conditions of the +Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available +at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. +For purposes of the EPL, "Program" will mean the Content.</p> + +<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is +being redistributed by another party ("Redistributor") and different terms and conditions may +apply to your use of any object code in the Content. Check the Redistributor's license that was +provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise +indicated below, the terms and conditions of the EPL still apply to any source code in the Content +and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> + +</body> +</html>
\ No newline at end of file diff --git a/plugins/com.windriver.tcf.dsf.ui/build.properties b/plugins/com.windriver.tcf.dsf.ui/build.properties new file mode 100644 index 000000000..e9863e281 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/plugins/com.windriver.tcf.dsf.ui/icons/tcf.gif b/plugins/com.windriver.tcf.dsf.ui/icons/tcf.gif Binary files differnew file mode 100644 index 000000000..3198679ae --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/icons/tcf.gif diff --git a/plugins/com.windriver.tcf.dsf.ui/plugin.properties b/plugins/com.windriver.tcf.dsf.ui/plugin.properties new file mode 100644 index 000000000..85a170935 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/plugin.properties @@ -0,0 +1,13 @@ +############################################################################### +# Copyright (c) 2007 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 +# http://www.eclipse.org/legal/epl-v10.html +# +# Contributors: +# Wind River Systems - initial implementation +############################################################################### +pluginName = TCF/DSF Integration UI +providerName = Eclipse.org + diff --git a/plugins/com.windriver.tcf.dsf.ui/plugin.xml b/plugins/com.windriver.tcf.dsf.ui/plugin.xml new file mode 100644 index 000000000..4da1ce1d0 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/plugin.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + + <extension point="com.windriver.debug.tcf.core.startup"/> + + <extension point="org.eclipse.debug.ui.launchConfigurationTabGroups"> + <launchConfigurationTabGroup + type="com.windriver.tcf.dsf.LaunchConfigurationType" + class="com.windriver.tcf.dsf.ui.LaunchDialogTabGroup" + id="org.eclipse.dd.dsf.mi.launch.localRunLaunchTabGroup"> + </launchConfigurationTabGroup> + </extension> + + <extension point="org.eclipse.debug.ui.launchConfigurationTypeImages"> + <launchConfigurationTypeImage + icon="icons/tcf.gif" + configTypeID="com.windriver.tcf.dsf.LaunchConfigurationType" + id="com.windriver.tcf.dsf.LaunchImage"> + </launchConfigurationTypeImage> + </extension> + + <extension point="org.eclipse.core.runtime.adapters"> + <factory + class="com.windriver.tcf.dsf.ui.AdapterFactory" + adaptableType="com.windriver.tcf.dsf.core.launch.TCFDSFLaunch"> + <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider"/> + <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider"/> + <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory"/> + <adapter type="org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory"/> + <adapter type="org.eclipse.debug.core.commands.ITerminateHandler"/> + </factory> + </extension> + +</plugin> diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/Activator.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/Activator.java new file mode 100644 index 000000000..f37328701 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/Activator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.windriver.tcf.dsf.ui"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/AdapterFactory.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/AdapterFactory.java new file mode 100644 index 000000000..f8d0604f8 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/AdapterFactory.java @@ -0,0 +1,207 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.dd.dsf.concurrent.Immutable; +import org.eclipse.dd.dsf.debug.ui.actions.DsfResumeCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepIntoCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepOverCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfStepReturnCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfSuspendCommand; +import org.eclipse.dd.dsf.debug.ui.actions.DsfTerminateCommand; +import org.eclipse.dd.dsf.debug.ui.sourcelookup.MISourceDisplayAdapter; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.core.commands.IResumeHandler; +import org.eclipse.debug.core.commands.IStepIntoHandler; +import org.eclipse.debug.core.commands.IStepOverHandler; +import org.eclipse.debug.core.commands.IStepReturnHandler; +import org.eclipse.debug.core.commands.ISuspendHandler; +import org.eclipse.debug.core.commands.ITerminateHandler; +import org.eclipse.debug.core.model.IDebugModelProvider; +import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementContentProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelProxyFactory; +import org.eclipse.debug.ui.sourcelookup.ISourceDisplay; + +import com.windriver.debug.tcf.core.model.ITCFConstants; +import com.windriver.tcf.dsf.core.launch.TCFDSFLaunch; + +@SuppressWarnings("restriction") +public class AdapterFactory implements IAdapterFactory, DsfSession.SessionEndedListener, ILaunchesListener2 { + + @Immutable + private final class SessionAdapterSet { + + private final DsfSession fSession; + final ViewModelAdapter fViewModelAdapter; + final MISourceDisplayAdapter fSourceDisplayAdapter; + final DsfStepIntoCommand fStepIntoCommand; + final DsfStepOverCommand fStepOverCommand; + final DsfStepReturnCommand fStepReturnCommand; + final DsfSuspendCommand fSuspendCommand; + final DsfResumeCommand fResumeCommand; + final DsfTerminateCommand fTerminateCommand; + final IDebugModelProvider fDebugModelProvider; + final TCFDSFLaunch fLaunch; + + SessionAdapterSet(DsfSession session, TCFDSFLaunch launch) { + fSession = session; + + fViewModelAdapter = new ViewModelAdapter(session, launch); + + if (launch.getSourceLocator() instanceof ISourceLookupDirector) { + fSourceDisplayAdapter = new MISourceDisplayAdapter(session, (ISourceLookupDirector)launch.getSourceLocator()); + } else { + fSourceDisplayAdapter = null; + } + session.registerModelAdapter(ISourceDisplay.class, fSourceDisplayAdapter); + + fStepIntoCommand = new DsfStepIntoCommand(session); + fStepOverCommand = new DsfStepOverCommand(session); + fStepReturnCommand = new DsfStepReturnCommand(session); + fSuspendCommand = new DsfSuspendCommand(session); + fResumeCommand = new DsfResumeCommand(session); + fTerminateCommand = new DsfTerminateCommand(session); + session.registerModelAdapter(IStepIntoHandler.class, fStepIntoCommand); + session.registerModelAdapter(IStepOverHandler.class, fStepOverCommand); + session.registerModelAdapter(IStepReturnHandler.class, fStepReturnCommand); + session.registerModelAdapter(ISuspendHandler.class, fSuspendCommand); + session.registerModelAdapter(IResumeHandler.class, fResumeCommand); + session.registerModelAdapter(ITerminateHandler.class, fTerminateCommand); + + fDebugModelProvider = new IDebugModelProvider() { + // @see org.eclipse.debug.core.model.IDebugModelProvider#getModelIdentifiers() + public String[] getModelIdentifiers() { + return new String[] { ITCFConstants.ID_TCF_DEBUG_MODEL }; + } + }; + session.registerModelAdapter(IDebugModelProvider.class, fDebugModelProvider); + + fLaunch = launch; + + /* + * Registering the launch as an adapter, ensures that this launch, + * and debug model ID will be associated with all DMContexts from this + * session. + */ + session.registerModelAdapter(ILaunch.class, fLaunch); + } + + void dispose() { + fViewModelAdapter.dispose(); + + fSession.unregisterModelAdapter(ISourceDisplay.class); + if (fSourceDisplayAdapter != null) fSourceDisplayAdapter.dispose(); + + fSession.unregisterModelAdapter(IStepIntoHandler.class); + fSession.unregisterModelAdapter(IStepOverHandler.class); + fSession.unregisterModelAdapter(IStepReturnHandler.class); + fSession.unregisterModelAdapter(ISuspendHandler.class); + fSession.unregisterModelAdapter(IResumeHandler.class); + fSession.unregisterModelAdapter(ITerminateHandler.class); + fStepIntoCommand.dispose(); + fStepOverCommand.dispose(); + fStepReturnCommand.dispose(); + fSuspendCommand.dispose(); + fResumeCommand.dispose(); + fTerminateCommand.dispose(); + } + } + + @SuppressWarnings({ "unchecked", "restriction" }) + private final Class[] adapter_list = { + IElementLabelProvider.class, + IElementContentProvider.class, + IColumnPresentationFactory.class, + IModelProxyFactory.class, + ITerminateHandler.class + }; + + private Map<String,SessionAdapterSet> fSessionAdapterSetMap = + Collections.synchronizedMap(new HashMap<String,SessionAdapterSet>()); + + public AdapterFactory() { + DsfSession.addSessionEndedListener(this); + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + @SuppressWarnings({ "restriction", "unchecked" }) + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (!(adaptableObject instanceof TCFDSFLaunch)) return null; + + TCFDSFLaunch launch = (TCFDSFLaunch)adaptableObject; + + // Find the correct set of adapters based on the launch session-ID. If not found + // it means that we have a new launch and new session, and we have to create a + // new set of adapters. + DsfSession session = launch.getSession(); + if (session == null) return null; + + SessionAdapterSet adapter_set; + synchronized(fSessionAdapterSetMap) { + adapter_set = fSessionAdapterSetMap.get(session.getId()); + if (adapter_set == null) { + adapter_set = new SessionAdapterSet(session, launch); + fSessionAdapterSetMap.put(session.getId(), adapter_set); + } + } + + // Returns the adapter type for the launch object. + if (adapterType.equals(IElementLabelProvider.class)) return adapter_set.fViewModelAdapter; + if (adapterType.equals(IElementContentProvider.class)) return adapter_set.fViewModelAdapter; + if (adapterType.equals(IModelProxyFactory.class)) return adapter_set.fViewModelAdapter; + if (adapterType.equals(IColumnPresentationFactory.class)) return adapter_set.fViewModelAdapter; + if (adapterType.equals(ITerminateHandler.class)) return adapter_set.fTerminateCommand; + return null; + } + + @SuppressWarnings("unchecked") + public Class[] getAdapterList() { + return adapter_list; + } + + public void sessionEnded(DsfSession session) { + } + + public void launchesTerminated(ILaunch[] launches) { + } + + public void launchesAdded(ILaunch[] launches) { + } + + public void launchesChanged(ILaunch[] launches) { + } + + public void launchesRemoved(ILaunch[] launches) { + // Dispose the set of adapters for a launch only after the launch is removed. + for (ILaunch launch : launches) { + if (launch instanceof TCFDSFLaunch) { + DsfSession session = ((TCFDSFLaunch)launch).getSession(); + synchronized (fSessionAdapterSetMap) { + if (fSessionAdapterSetMap.containsKey(session.getId())) { + fSessionAdapterSetMap.get(session.getId()).dispose(); + fSessionAdapterSetMap.remove(session); + } + } + } + } + } +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ContainerLayoutNode.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ContainerLayoutNode.java new file mode 100644 index 000000000..31d80eba3 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ContainerLayoutNode.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Ericsson - Initial API and implementation + * Wind River Systems - reused for TCF connection type + *******************************************************************************/ + +package com.windriver.tcf.dsf.ui; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.debug.service.INativeProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.INativeProcesses.IProcessDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; + +import com.windriver.tcf.dsf.core.services.TCFDSFRunControl; + +@SuppressWarnings("restriction") +public class ContainerLayoutNode extends AbstractDMVMLayoutNode{ + + public ContainerLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IRunControl.IExecutionDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(IChildrenUpdate update) { + if (!checkService(IRunControl.class, null, update)) return; + + IContainerDMContext containerCtx = getServicesTracker().getService(TCFDSFRunControl.class).getContainerDMC(); + update.setChild(new DMVMContext(containerCtx), 0); + update.done(); + } + + @Override + // Labels are only updated for elements that are visible. + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + if (!checkService(IRunControl.class, null, update)) continue; + if (!checkService(INativeProcesses.class, null, update)) continue; + + final IContainerDMContext dmc = findDmcInPath(update.getElementPath(), IContainerDMContext.class); + + INativeProcesses processes = getServicesTracker().getService(INativeProcesses.class); + + String imageKey = null; + + if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + processes.getProcessData( + processes.getProcessForDebugContext(dmc), + new DataRequestMonitor<IProcessDMData>(getSession().getExecutor(), null) { + @SuppressWarnings("restriction") + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + update.setLabel(getData().getName(), 0); + update.done(); + } + }); + } + } +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchDialogTabGroup.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchDialogTabGroup.java new file mode 100644 index 000000000..9a7d62dcc --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchDialogTabGroup.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.EnvironmentTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +import com.windriver.debug.tcf.ui.launch.TCFArgumentsTab; +import com.windriver.debug.tcf.ui.launch.TCFMainTab; + +/** + * Launch configuration dialog tab group for TCF over DSF + */ +public class LaunchDialogTabGroup extends AbstractLaunchConfigurationTabGroup { + + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + setTabs(new ILaunchConfigurationTab[] { + new TCFMainTab(), + new TCFArgumentsTab(), + new EnvironmentTab(), + new SourceLookupTab(), + new CommonTab() + }); + } +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchVMProvider.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchVMProvider.java new file mode 100644 index 000000000..caf259806 --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/LaunchVMProvider.java @@ -0,0 +1,161 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import java.util.concurrent.RejectedExecutionException; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StackFramesLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardLaunchRootLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardProcessLayoutNode; +import org.eclipse.dd.dsf.debug.ui.viewmodel.launch.StandardLaunchRootLayoutNode.LaunchesEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.IVMRootLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.core.DebugEvent; +import org.eclipse.debug.core.DebugPlugin; +import org.eclipse.debug.core.IDebugEventSetListener; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.ILaunchesListener2; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; + + +@SuppressWarnings("restriction") +public class LaunchVMProvider extends AbstractDMVMProvider + implements IDebugEventSetListener, ILaunchesListener2 { + + @ThreadSafe + public LaunchVMProvider(AbstractVMAdapter adapter, IPresentationContext presentationContext, + DsfSession session, ILaunch launch) + { + super(adapter, presentationContext, session); + + IVMRootLayoutNode launchNode = new StandardLaunchRootLayoutNode(this, launch); + // Container node to contain all processes and threads + IVMLayoutNode containerNode = new ContainerLayoutNode(this, getSession()); + IVMLayoutNode processesNode = new StandardProcessLayoutNode(this); + launchNode.setChildNodes(new IVMLayoutNode[] { containerNode, processesNode}); + + IVMLayoutNode threadsNode = new ThreadLayoutNode(this, getSession()); + containerNode.setChildNodes(new IVMLayoutNode[] { threadsNode }); + + IVMLayoutNode stackFramesNode = new StackFramesLayoutNode(this, getSession()); + threadsNode.setChildNodes(new IVMLayoutNode[] { stackFramesNode }); + + setRootLayoutNode(launchNode); + + DebugPlugin.getDefault().addDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this); + } + + + public void handleDebugEvents(final DebugEvent[] events) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + for (final DebugEvent event : events) { + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + rootLayoutNode.createDelta( + event, + new DataRequestMonitor<IModelDelta>(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } + } + @Override + public String toString() { + return "Result of a delta for debug event: '" + event.toString() + + "' in VMP: '" + LaunchVMProvider.this + "'" + + "\n" + getData(); + } + }); + } + } + }}); + } + catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } + + @Override + public void dispose() { + DebugPlugin.getDefault().removeDebugEventListener(this); + DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); + super.dispose(); + } + + public void launchesAdded(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.ADDED)); + } + + public void launchesRemoved(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.REMOVED)); + } + + public void launchesChanged(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.CHANGED)); + } + + public void launchesTerminated(ILaunch[] launches) { + handleLaunchesEvent(new LaunchesEvent(launches, LaunchesEvent.Type.TERMINATED)); + } + + private void handleLaunchesEvent(final LaunchesEvent event) { + if (isDisposed()) return; + + // We're in session's executor thread. Re-dispach to VM Adapter + // executor thread and then call root layout node. + try { + getExecutor().execute(new Runnable() { + public void run() { + if (isDisposed()) return; + + IVMRootLayoutNode rootLayoutNode = getRootLayoutNode(); + if (rootLayoutNode != null && rootLayoutNode.getDeltaFlags(event) != 0) { + rootLayoutNode.createDelta( + event, + new DataRequestMonitor<IModelDelta>(getExecutor(), null) { + @Override + public void handleCompleted() { + if (getStatus().isOK()) { + getModelProxy().fireModelChangedNonDispatch(getData()); + } + } + @Override public String toString() { + return "Result of a delta for launch event: '" + event.toString() + + "' in VMP: '" + LaunchVMProvider.this + "'" + + "\n" + getData(); + } + }); + } + }}); + } + catch (RejectedExecutionException e) { + // Ignore. This exception could be thrown if the provider is being + // shut down. + } + } +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ThreadLayoutNode.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ThreadLayoutNode.java new file mode 100644 index 000000000..54ef832fc --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ThreadLayoutNode.java @@ -0,0 +1,197 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + * Ericsson - Modified for multi threaded functionality + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import java.util.List; +import java.util.Map; + +import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; +import org.eclipse.dd.dsf.concurrent.RequestMonitor; +import org.eclipse.dd.dsf.datamodel.IDMEvent; +import org.eclipse.dd.dsf.debug.service.INativeProcesses; +import org.eclipse.dd.dsf.debug.service.IRunControl; +import org.eclipse.dd.dsf.debug.service.INativeProcesses.IThreadDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IContainerDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMContext; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExecutionDMData; +import org.eclipse.dd.dsf.debug.service.IRunControl.IExitedDMEvent; +import org.eclipse.dd.dsf.debug.service.IRunControl.IStartedDMEvent; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.AbstractVMProvider; +import org.eclipse.dd.dsf.ui.viewmodel.IVMContext; +import org.eclipse.dd.dsf.ui.viewmodel.IVMLayoutNode; +import org.eclipse.dd.dsf.ui.viewmodel.VMDelta; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMLayoutNode; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IChildrenUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IModelDelta; +import org.eclipse.debug.ui.DebugUITools; +import org.eclipse.debug.ui.IDebugUIConstants; + +import com.windriver.tcf.dsf.core.services.TCFDSFExecutionDMC; + +@SuppressWarnings("restriction") +public class ThreadLayoutNode extends AbstractDMVMLayoutNode { + + public ThreadLayoutNode(AbstractVMProvider provider, DsfSession session) { + super(provider, session, IRunControl.IExecutionDMContext.class); + } + + @Override + protected void updateElementsInSessionThread(final IChildrenUpdate update) { + if (!checkService(IRunControl.class, null, update)) return; + final IContainerDMContext contDmc = findDmcInPath(update.getElementPath(), IContainerDMContext.class); + + if (contDmc == null) { + handleFailedUpdate(update); + return; + } + + getServicesTracker().getService(IRunControl.class).getExecutionContexts(contDmc, + new DataRequestMonitor<IExecutionDMContext[]>(getSession().getExecutor(), null){ + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + handleFailedUpdate(update); + return; + } + fillUpdateWithVMCs(update, getData()); + update.done(); + } + }); + } + + @Override + protected void updateLabelInSessionThread(ILabelUpdate[] updates) { + for (final ILabelUpdate update : updates) { + if (!checkService(IRunControl.class, null, update)) continue; + if (!checkService(INativeProcesses.class, null, update)) continue; + + final IExecutionDMContext dmc = findDmcInPath(update.getElementPath(), IExecutionDMContext.class); + + INativeProcesses processes = getServicesTracker().getService(INativeProcesses.class); + + String imageKey = null; + if (getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_SUSPENDED; + } + else { + imageKey = IDebugUIConstants.IMG_OBJS_THREAD_RUNNING; + } + update.setImageDescriptor(DebugUITools.getImageDescriptor(imageKey), 0); + + // Find the Reason for the State + final StringBuilder reason = new StringBuilder(); + getServicesTracker().getService(IRunControl.class).getExecutionData(dmc, + new DataRequestMonitor<IExecutionDMData>(getSession().getExecutor(), null) { + @Override + public void handleCompleted(){ + if (!getStatus().isOK()) { + update.done(); + return; + } + if(getData().getStateChangeReason() != null){ + reason.append(": " + getData().getStateChangeReason() ); //$NON-NLS-1$ + } + } + }); + + getServicesTracker().getService(INativeProcesses.class).getThreadData( + processes.getThreadForDebugContext(dmc), + new DataRequestMonitor<IThreadDMData>(getSession().getExecutor(), null) { + @Override + public void handleCompleted() { + if (!getStatus().isOK()) { + update.done(); + return; + } + final StringBuilder builder = new StringBuilder("Thread["); //$NON-NLS-1$ + builder.append(((TCFDSFExecutionDMC)dmc).getTcfContextId()); + builder.append("] "); //$NON-NLS-1$ + builder.append(getData().getId()); + builder.append(getData().getName()); + if(getServicesTracker().getService(IRunControl.class).isSuspended(dmc)) + builder.append(" (Suspended"); //$NON-NLS-1$ + else + builder.append(" (Running"); //$NON-NLS-1$ + // Reason will be null before ContainerSuspendEvent is fired + if(reason.length() > 0 ) + builder.append(reason); + builder.append(")"); //$NON-NLS-1$ + update.setLabel(builder.toString(), 0); + update.done(); + } + }); + } + } + + @Override + protected int getNodeDeltaFlagsForDMEvent(IDMEvent<?> e) { + if(e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent || e instanceof IStartedDMEvent || e instanceof IExitedDMEvent) { + return IModelDelta.CONTENT; + } + if(e instanceof IRunControl.IResumedDMEvent || e instanceof IRunControl.ISuspendedDMEvent) { + return IModelDelta.STATE; + } + return IModelDelta.NO_CHANGE; + } + + @Override + protected void buildDeltaForDMEvent(final IDMEvent<?> e, final VMDelta parentDelta, final int nodeOffset, final RequestMonitor requestMonitor) { + if(e instanceof IRunControl.IContainerResumedDMEvent || e instanceof IRunControl.IContainerSuspendedDMEvent) { + // Since IContainerDMContext sub-classes IExecutionDMContext, container + // events require special processing: + // Retrieve all the thread elements and mark their state as changed. + // Then pass these elements to the child layout nodes for processing + final Map<IVMLayoutNode,Integer> childNodeDeltas = getChildNodesWithDeltaFlags(e); + if (childNodeDeltas.size() == 0) { + // There are no child nodes with deltas, just return to parent. + requestMonitor.done(); + return; + } + + // Calculate the index of this node by retrieving all the + // elements and then finding the DMC that the event is for. + updateElements(new ElementsUpdate( + new DataRequestMonitor<List<Object>>(getExecutor(), null) { + @Override + protected void handleCompleted() { + if (isDisposed()) return; + + // Check for an empty list of elements. If it's empty then we + // don't have to call the children nodes, so return here. + // No need to propagate error, there's no means or need to display it. + if (!getStatus().isOK() || getData().isEmpty()) { + requestMonitor.done(); + return; + } + + for (int i = 0; i < getData().size(); i++) { + IVMContext vmc = (IVMContext)getData().get(i); + VMDelta delta = parentDelta.addNode(vmc, nodeOffset + i, IModelDelta.STATE); + callChildNodesToBuildDelta(childNodeDeltas, delta, e, requestMonitor); + if (vmc.equals(getData().get(i))) break; + } + } + }, + parentDelta)); + return; + } + else if (e instanceof IRunControl.IResumedDMEvent || e instanceof IRunControl.ISuspendedDMEvent) { + parentDelta.addNode(new DMVMContext(e.getDMContext()), IModelDelta.STATE); + super.buildDeltaForDMEvent(e, parentDelta, nodeOffset, requestMonitor); + } + else { + super.buildDeltaForDMEvent(e, parentDelta, nodeOffset, requestMonitor); + } + } +} diff --git a/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ViewModelAdapter.java b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ViewModelAdapter.java new file mode 100644 index 000000000..e70d2704c --- /dev/null +++ b/plugins/com.windriver.tcf.dsf.ui/src/com/windriver/tcf/dsf/ui/ViewModelAdapter.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package com.windriver.tcf.dsf.ui; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; +import org.eclipse.dd.dsf.concurrent.ThreadSafe; +import org.eclipse.dd.dsf.debug.ui.viewmodel.expression.ExpressionVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.register.RegisterVMProvider; +import org.eclipse.dd.dsf.debug.ui.viewmodel.variable.VariableVMProvider; +import org.eclipse.dd.dsf.service.DsfSession; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMAdapter; +import org.eclipse.dd.dsf.ui.viewmodel.dm.AbstractDMVMProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IColumnPresentationFactory; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IElementLabelProvider; +import org.eclipse.debug.internal.ui.viewers.model.provisional.ILabelUpdate; +import org.eclipse.debug.internal.ui.viewers.model.provisional.IPresentationContext; +import org.eclipse.debug.ui.IDebugUIConstants; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; +import org.osgi.framework.Bundle; + +import com.windriver.tcf.api.protocol.Protocol; +import com.windriver.tcf.dsf.core.launch.TCFDSFLaunch; + +@ThreadSafe +@SuppressWarnings("restriction") +public class ViewModelAdapter extends AbstractDMVMAdapter implements IElementLabelProvider { + + private final TCFDSFLaunch launch; + + public ViewModelAdapter(DsfSession session, TCFDSFLaunch launch) { + super(session); + this.launch = launch; + getSession().registerModelAdapter(IColumnPresentationFactory.class, this); + } + + @Override + public void dispose() { + getSession().unregisterModelAdapter(IColumnPresentationFactory.class); + super.dispose(); + } + + @Override + protected AbstractDMVMProvider createViewModelProvider(IPresentationContext context) { + if (IDebugUIConstants.ID_DEBUG_VIEW.equals(context.getId()) ) { + return new LaunchVMProvider(this, context, getSession(), launch); + } + if (IDebugUIConstants.ID_VARIABLE_VIEW.equals(context.getId()) ) { + return new VariableVMProvider(this, context, getSession()); + } + if (IDebugUIConstants.ID_REGISTER_VIEW.equals(context.getId()) ) { + return new RegisterVMProvider(this, context, getSession()); + } + if (IDebugUIConstants.ID_EXPRESSION_VIEW.equals(context.getId()) ) { + return new ExpressionVMProvider(this, context, getSession()); + } + return null; + } + + private static final Map<String,ImageDescriptor> image_cache = + new HashMap<String,ImageDescriptor>(); + + private static ImageDescriptor getImageDescriptor(String name) { + if (name == null) return null; + ImageDescriptor descriptor = image_cache.get(name); + if (descriptor == null) { + descriptor = ImageDescriptor.getMissingImageDescriptor(); + Bundle bundle = Platform.getBundle("org.eclipse.debug.ui"); + if (bundle != null){ + URL url = FileLocator.find(bundle, new Path(name), null); + descriptor = ImageDescriptor.createFromURL(url); + } + image_cache.put(name, descriptor); + } + return descriptor; + } + + public void update(final ILabelUpdate[] updates) { + Protocol.invokeLater(new Runnable() { + public void run() { + for (ILabelUpdate u : updates) { + Object o = u.getElement(); + if (o instanceof TCFDSFLaunch) { + u.setImageDescriptor(getImageDescriptor("icons/full/obj16/ldebug_obj.gif"), 0); + TCFDSFLaunch launch = (TCFDSFLaunch)o; + String status = ""; + if (launch.isConnecting()) status = "Connecting"; + else if (launch.isDisconnected()) status = "Disconnected"; + else if (launch.isTerminated()) status = "Terminated"; + Throwable error = launch.getError(); + if (error != null) { + status += " - " + error; + u.setForeground(new RGB(255, 0, 0), 0); + } + if (status.length() > 0) status = " (" + status + ")"; + u.setLabel(launch.getLaunchConfiguration().getName() + status, 0); + } + else { + u.setForeground(new RGB(255, 0, 0), 0); + u.setLabel("Invalid object: " + o.getClass(), 0); + } + } + Display.getDefault().asyncExec(new Runnable() { + public void run() { + for (ILabelUpdate u : updates) u.done(); + } + }); + } + }); + } +} |