| /******************************************************************************* |
| * Copyright (c) 2011, 2014 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 org.eclipse.tcf.te.tcf.launch.ui.internal.services; |
| |
| import java.util.concurrent.CancellationException; |
| import java.util.concurrent.ExecutionException; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.debug.core.DebugPlugin; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.ILaunchConfiguration; |
| import org.eclipse.debug.core.ILaunchConfigurationType; |
| import org.eclipse.debug.core.ILaunchListener; |
| import org.eclipse.debug.core.ILaunchManager; |
| import org.eclipse.debug.core.ILaunchesListener; |
| import org.eclipse.debug.core.model.IDisconnect; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.tcf.protocol.Protocol; |
| import org.eclipse.tcf.te.launch.core.lm.LaunchManager; |
| import org.eclipse.tcf.te.launch.core.lm.interfaces.ILaunchManagerDelegate; |
| import org.eclipse.tcf.te.launch.core.lm.interfaces.ILaunchSpecification; |
| import org.eclipse.tcf.te.launch.core.persistence.launchcontext.LaunchContextsPersistenceDelegate; |
| import org.eclipse.tcf.te.launch.core.selection.LaunchSelection; |
| import org.eclipse.tcf.te.launch.core.selection.RemoteSelectionContext; |
| import org.eclipse.tcf.te.launch.core.selection.interfaces.ILaunchSelection; |
| import org.eclipse.tcf.te.runtime.concurrent.util.ExecutorsUtil; |
| import org.eclipse.tcf.te.runtime.interfaces.callback.ICallback; |
| import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; |
| import org.eclipse.tcf.te.runtime.model.interfaces.IModelNode; |
| import org.eclipse.tcf.te.runtime.services.AbstractService; |
| import org.eclipse.tcf.te.runtime.services.interfaces.IDebugService; |
| import org.eclipse.tcf.te.runtime.utils.StatusHelper; |
| import org.eclipse.tcf.te.tcf.launch.core.delegates.Launch; |
| import org.eclipse.tcf.te.tcf.launch.core.interfaces.ILaunchTypes; |
| import org.eclipse.tcf.te.ui.swt.DisplayUtil; |
| |
| /** |
| * Debug service implementations for TCF contexts. |
| */ |
| public class DebugService extends AbstractService implements IDebugService { |
| // Reference to the launches listener |
| private final ILaunchesListener listener; |
| |
| /** |
| * Constructor |
| */ |
| public DebugService() { |
| super(); |
| |
| // Create and register the launches listener instance |
| listener = new DebugServicesLaunchesListener(); |
| DebugPlugin.getDefault().getLaunchManager().addLaunchListener(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.tcf.te.runtime.services.interfaces.IDebugService#attach(java.lang.Object, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback) |
| */ |
| @Override |
| public void attach(final Object context, final IPropertiesContainer data, final IProgressMonitor monitor, final ICallback callback) { |
| if (!Protocol.isDispatchThread()) { |
| internalAttach(context, data, monitor, callback); |
| } |
| else { |
| ExecutorsUtil.execute(new Runnable() { |
| @Override |
| public void run() { |
| internalAttach(context, data, monitor, callback); |
| } |
| }); |
| } |
| } |
| |
| @SuppressWarnings("restriction") |
| protected void internalAttach(final Object context, final IPropertiesContainer data, final IProgressMonitor monitor, final ICallback callback) { |
| Assert.isTrue(!Protocol.isDispatchThread(), "Illegal Thread Access"); //$NON-NLS-1$ |
| |
| Assert.isNotNull(context); |
| Assert.isNotNull(data); |
| Assert.isNotNull(callback); |
| |
| if (context instanceof IModelNode) { |
| ILaunchConfigurationType launchConfigType = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(ILaunchTypes.ATTACH); |
| try { |
| ILaunchSelection launchSelection = new LaunchSelection(ILaunchManager.DEBUG_MODE, new RemoteSelectionContext((IModelNode)context, true)); |
| ILaunchManagerDelegate delegate = LaunchManager.getInstance().getLaunchManagerDelegate(launchConfigType, ILaunchManager.DEBUG_MODE); |
| if (delegate != null) { |
| // create an empty launch configuration specification to initialize all attributes with their default defaults. |
| ILaunchSpecification launchSpec = delegate.getLaunchSpecification(launchConfigType.getIdentifier(), launchSelection); |
| for (String key : data.getProperties().keySet()) { |
| launchSpec.addAttribute(key, data.getProperty(key)); |
| } |
| delegate.validate(launchSpec); |
| if (launchSpec != null && launchSpec.isValid()) { |
| ILaunchConfiguration[] launchConfigs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(launchConfigType); |
| launchConfigs = delegate.getMatchingLaunchConfigurations(launchSpec, launchConfigs); |
| |
| ILaunchConfiguration config = launchConfigs != null && launchConfigs.length > 0 ? launchConfigs[0] : null; |
| |
| boolean skip = false; |
| ILaunch activeLaunch = null; |
| if (config != null) { |
| ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); |
| for (ILaunch launch : launches) { |
| if (launch.getLaunchConfiguration().getType().getIdentifier().equals(ILaunchTypes.ATTACH) && !launch.isTerminated()) { |
| IModelNode[] contexts = LaunchContextsPersistenceDelegate.getLaunchContexts(launch.getLaunchConfiguration()); |
| if (contexts != null && contexts.length == 1 && contexts[0].equals(context)) { |
| callback.setProperty("launch", launch); //$NON-NLS-1$ |
| activeLaunch = launch; |
| skip = true; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (!skip) { |
| final ILaunchConfiguration finConfig = LaunchManager.getInstance().createOrUpdateLaunchConfiguration(config, launchSpec); |
| |
| delegate.validate(ILaunchManager.DEBUG_MODE, finConfig); |
| |
| final ILaunchListener listener = new ILaunchListener() { |
| @Override |
| public void launchAdded(ILaunch launch) { |
| if (launch != null && finConfig.equals(launch.getLaunchConfiguration())) { |
| DebugPlugin.getDefault().getLaunchManager().removeLaunchListener(this); |
| callback.setProperty("launch", launch); //$NON-NLS-1$ |
| if (launch instanceof Launch) { |
| ((Launch)launch).setCallback(callback); |
| } |
| else { |
| callback.done(this, Status.OK_STATUS); |
| } |
| } |
| } |
| |
| @Override |
| public void launchChanged(ILaunch launch) { |
| } |
| |
| @Override |
| public void launchRemoved(ILaunch launch) { |
| } |
| }; |
| |
| DebugPlugin.getDefault().getLaunchManager().addLaunchListener(listener); |
| |
| // DebugUITools.launch(...) must be called from within the UI thread. |
| DisplayUtil.safeAsyncExec(new Runnable() { |
| @Override |
| public void run() { |
| try { |
| DebugUITools.buildAndLaunch(finConfig, ILaunchManager.DEBUG_MODE, monitor != null ? monitor : new NullProgressMonitor()); |
| } |
| catch (Exception e) { |
| callback.done(DebugService.this, StatusHelper.getStatus(e)); |
| } |
| } |
| }); |
| } else { |
| org.eclipse.debug.internal.ui.DebugUIPlugin.getDefault().getPerspectiveManager().launchAdded(activeLaunch); |
| callback.done(this, Status.OK_STATUS); |
| } |
| } |
| } |
| } |
| catch (Exception e) { |
| callback.done(this, StatusHelper.getStatus(e)); |
| } |
| } |
| else { |
| callback.done(this, Status.OK_STATUS); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.tcf.te.runtime.services.interfaces.IDebugService#detach(java.lang.Object, org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.core.runtime.IProgressMonitor, org.eclipse.tcf.te.runtime.interfaces.callback.ICallback) |
| */ |
| @Override |
| public void detach(Object context, IPropertiesContainer data, final IProgressMonitor monitor, ICallback callback) { |
| Assert.isNotNull(context); |
| Assert.isNotNull(data); |
| Assert.isNotNull(callback); |
| |
| if (context instanceof IModelNode) { |
| ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); |
| for (ILaunch launch : launches) { |
| try { |
| if (launch.getLaunchConfiguration().getType().getIdentifier().equals(ILaunchTypes.ATTACH)) { |
| IModelNode[] contexts = LaunchContextsPersistenceDelegate.getLaunchContexts(launch.getLaunchConfiguration()); |
| if (contexts != null && contexts.length == 1 && contexts[0].equals(context)) { |
| if (launch instanceof IDisconnect && !((IDisconnect)launch).isDisconnected()) { |
| ((IDisconnect)launch).disconnect(); |
| data.setProperty(PROPERTY_DEBUGGER_DETACHED, true); |
| } |
| else if (launch instanceof Launch) { |
| data.setProperty(PROPERTY_DEBUGGER_DETACHED, !((Launch)launch).isManualDisconnected()); |
| } |
| } |
| } |
| } catch (Exception e) { |
| if (e instanceof ExecutionException && "TCF task aborted".equals(e.getMessage()) //$NON-NLS-1$ |
| || e.getCause() instanceof CancellationException) { |
| // This disconnect of the debug launch timed out. We are going |
| // to ignore this as we are detaching from the debugger anyway. |
| callback.done(this, Status.OK_STATUS); |
| } else { |
| callback.done(this, StatusHelper.getStatus(e)); |
| } |
| return; |
| } |
| } |
| } |
| callback.done(this, Status.OK_STATUS); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.tcf.te.runtime.services.interfaces.IDebugService#isLaunched(java.lang.Object) |
| */ |
| @Override |
| public boolean isLaunched(Object context) { |
| Assert.isNotNull(context); |
| |
| boolean isLaunched = false; |
| |
| if (context instanceof IModelNode) { |
| ILaunch[] launches = DebugPlugin.getDefault().getLaunchManager().getLaunches(); |
| for (ILaunch launch : launches) { |
| if (launch == null) continue; |
| try { |
| if (launch.getLaunchConfiguration() != null && launch.getLaunchConfiguration().getType() != null && launch.getLaunchConfiguration().getType().getIdentifier() != null) { |
| if (launch.getLaunchConfiguration().getType().getIdentifier().equals(ILaunchTypes.ATTACH) && !launch.isTerminated()) { |
| IModelNode[] contexts = LaunchContextsPersistenceDelegate.getLaunchContexts(launch.getLaunchConfiguration()); |
| if (contexts != null && contexts.length == 1 && contexts[0].equals(context)) { |
| isLaunched = true; |
| break; |
| } |
| } |
| } |
| } catch (CoreException e) { |
| if (Platform.inDebugMode()) e.printStackTrace(); |
| } |
| } |
| } |
| |
| return isLaunched; |
| } |
| } |