/******************************************************************************* * Copyright (c) 2005, 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Bjorn Freeman-Benson - initial API and implementation * Wind River Systems - adopted to use with DSF *******************************************************************************/ package org.eclipse.cdt.examples.dsf.pda.launch; import java.util.concurrent.ExecutionException; import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor; import org.eclipse.cdt.dsf.concurrent.IDsfStatusConstants; import org.eclipse.cdt.dsf.concurrent.Query; import org.eclipse.cdt.dsf.service.DsfServicesTracker; import org.eclipse.cdt.examples.dsf.pda.PDAPlugin; import org.eclipse.cdt.examples.dsf.pda.service.PDABackend; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.model.IPersistableSourceLocator; import org.eclipse.debug.core.model.ISourceLocator; import org.eclipse.debug.core.model.LaunchConfigurationDelegate; import org.eclipse.debug.core.sourcelookup.IPersistableSourceLocator2; /** * Launches PDA program on a PDA interpretter written in Perl */ public class PDALaunchDelegate extends LaunchConfigurationDelegate { @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { // Need to configure the source locator before creating the launch // because once the launch is created and added to launch manager, // the adapters will be created for the whole session, including // the source lookup adapter. ISourceLocator locator = getSourceLocator(configuration); return new PDALaunch(configuration, mode, locator); } @Override public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor) throws CoreException { // PDA programs do not require building. return false; } /** * Returns a source locator created based on the attributes in the launch configuration. */ private ISourceLocator getSourceLocator(ILaunchConfiguration configuration) throws CoreException { String type = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, (String)null); if (type == null) { type = configuration.getType().getSourceLocatorId(); } if (type != null) { IPersistableSourceLocator locator = DebugPlugin.getDefault().getLaunchManager().newSourceLocator(type); String memento = configuration.getAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_MEMENTO, (String)null); if (memento == null) { locator.initializeDefaults(configuration); } else { if(locator instanceof IPersistableSourceLocator2) ((IPersistableSourceLocator2)locator).initializeFromMemento(memento, configuration); else locator.initializeFromMemento(memento); } return locator; } return null; } public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { String program = configuration.getAttribute(PDAPlugin.ATTR_PDA_PROGRAM, (String)null); if (program == null) { abort("Perl program unspecified.", null); } PDALaunch pdaLaunch = (PDALaunch)launch; initServices(pdaLaunch, program); createProcess(pdaLaunch); } /** * Calls the launch to initialize DSF services for this launch. */ private void initServices(final PDALaunch pdaLaunch, final String program) throws CoreException { // Synchronization object to use when waiting for the services initialization. Query<Object> initQuery = new Query<Object>() { @Override protected void execute(DataRequestMonitor<Object> rm) { pdaLaunch.initializeServices(program, rm); } }; // Submit the query to the executor. pdaLaunch.getSession().getExecutor().execute(initQuery); try { // Block waiting for query results. initQuery.get(); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ } } private void createProcess(final PDALaunch pdaLaunch) throws CoreException { // Synchronization object to use when waiting for the services initialization. Query<Object[]> initQuery = new Query<Object[]>() { @Override protected void execute(DataRequestMonitor<Object[]> rm) { DsfServicesTracker tracker = new DsfServicesTracker(PDAPlugin.getBundleContext(), pdaLaunch.getSession().getId()); PDABackend backend = tracker.getService(PDABackend.class); if (backend == null) { PDAPlugin.failRequest(rm, IDsfStatusConstants.INVALID_STATE, "PDA Backend service not available"); return; } Object[] retVal = new Object[] { backend.getProcess(), backend.getProcessName() }; rm.setData(retVal); rm.done(); } }; // Submit the query to the executor. pdaLaunch.getSession().getExecutor().execute(initQuery); try { // Block waiting for query results. Object[] processData = initQuery.get(); DebugPlugin.newProcess(pdaLaunch, (Process)processData[0], (String)processData[1]); } catch (InterruptedException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.INTERNAL_ERROR, "Interrupted Exception in dispatch thread", e1)); //$NON-NLS-1$ } catch (ExecutionException e1) { throw new DebugException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, DebugException.REQUEST_FAILED, "Error in launch sequence", e1.getCause())); //$NON-NLS-1$ } } /** * Throws an exception with a new status containing the given * message and optional exception. * * @param message error message * @param e underlying exception * @throws CoreException */ private void abort(String message, Throwable e) throws CoreException { throw new CoreException(new Status(IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, message, e)); } }