/**
* Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
/*
* Author: atotic
* Created: Aug 16, 2003
*/
package org.python.pydev.debug.ui.launching;
import java.io.IOException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.swt.widgets.Display;
import org.python.pydev.core.MisconfigurationException;
import org.python.pydev.core.log.Log;
import org.python.pydev.debug.core.Constants;
import org.python.pydev.debug.core.PydevDebugPlugin;
import org.python.pydev.editor.actions.PyAction;
import org.python.pydev.plugin.PydevPlugin;
/**
*
* Launcher for the python scripts.
*
* <p>The code is pretty much copied from ExternalTools' ProgramLaunchDelegate.
* <p>I would have subclassed, but ProgramLaunchDelegate hides important internals
*
* Based on org.eclipse.ui.externaltools.internal.program.launchConfigurations.ProgramLaunchDelegate
*
* Build order based on org.eclipse.jdt.launching.AbstractJavaLaunchConfigurationDelegate
*/
public abstract class AbstractLaunchConfigurationDelegate extends LaunchConfigurationDelegate implements
ILaunchConfigurationDelegate {
private IProject[] fOrderedProjects;
/**
* We need to reimplement this method (otherwise, all the projects in the workspace will be rebuilt, and not only
* the ones referenced in the configuration).
*/
@Override
protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String mode) throws CoreException {
return fOrderedProjects;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration,
* java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public boolean preLaunchCheck(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor)
throws CoreException {
// build project list
fOrderedProjects = null;
String projName = configuration.getAttribute(Constants.ATTR_PROJECT, "");
if (projName.length() > 0) {
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projName);
if (project != null) {
fOrderedProjects = computeReferencedBuildOrder(new IProject[] { project });
}
}
// do generic launch checks
return super.preLaunchCheck(configuration, mode, monitor);
}
/**
* Launches the python process.
*
* Modelled after Ant & Java runners
* see WorkbenchLaunchConfigurationDelegate::launch
*/
public void launch(ILaunchConfiguration conf, String mode, ILaunch launch, IProgressMonitor monitor)
throws CoreException {
if (monitor == null) {
monitor = new NullProgressMonitor();
}
monitor.beginTask("Preparing configuration", 3);
try {
PythonRunnerConfig runConfig = new PythonRunnerConfig(conf, mode, getRunnerConfigRun(conf, mode, launch));
monitor.worked(1);
try {
PythonRunner.run(runConfig, launch, monitor);
} catch (IOException e) {
Log.log(e);
finishLaunchWithError(launch);
throw new CoreException(PydevDebugPlugin.makeStatus(IStatus.ERROR,
"Unexpected IO Exception in Pydev debugger", null));
}
} catch (final InvalidRunException e) {
handleError(launch, e);
} catch (final MisconfigurationException e) {
handleError(launch, e);
}
}
private void handleError(ILaunch launch, final Exception e) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
ErrorDialog.openError(PyAction.getShell(), "Invalid launch configuration",
"Unable to make launch because launch configuration is not valid",
PydevPlugin.makeStatus(IStatus.ERROR, e.getMessage(), e));
}
});
finishLaunchWithError(launch);
}
private void finishLaunchWithError(ILaunch launch) {
try {
launch.terminate();
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
launchManager.removeLaunch(launch);
} catch (Throwable x) {
Log.log(x);
}
}
/**
* @return the mode we should use to run it...
*
* @see PythonRunnerConfig#RUN_REGULAR
* @see PythonRunnerConfig#RUN_COVERAGE
* @see PythonRunnerConfig#RUN_UNITTEST
* @see PythonRunnerConfig#RUN_JYTHON_UNITTEST
* @see PythonRunnerConfig#RUN_JYTHON
* @see PythonRunnerConfig#RUN_IRONPYTHON
* @see PythonRunnerConfig#RUN_IRONPYTHON_UNITTEST
*/
protected abstract String getRunnerConfigRun(ILaunchConfiguration conf, String mode, ILaunch launch);
}