blob: 6ec2139aa3bac604d4eadd069dddf58454d805e3 [file] [log] [blame]
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
package org.eclipse.jdt.internal.junit.ui;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILauncher;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.ILauncherDelegate;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.ProjectSourceLocator;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import org.eclipse.jdt.launching.VMRunnerResult;
/**
* An abstract base launcher for running JUnit TestSuites.
* Subclasses have to override: VMRunnerConfiguration configureVM(IType[] testTypes, int port)
*/
public abstract class JUnitBaseLauncherDelegate implements ILauncherDelegate, IJUnitLauncherDelegate {
/**
* The run mode used to invoke the launcher.
*/
private String fRunMode;
/**
* The port we are connecting to
*/
private int fPort;
/**
* The type to be launched
*/
private IType fType;
/**
* The launcher
*/
private ILauncher fLauncher;
/**
* Configure a VM for the given test types.
*/
protected abstract VMRunnerConfiguration configureVM(IType[] testTypes, int port, String mode) throws CoreException;
/*
* @see ILauncherDelegate#launch(Object[], String, ILauncher)
*/
public boolean launch(Object[] objects, String mode, ILauncher launcher) {
IStructuredSelection selection= new StructuredSelection(objects);
Object[] elements= getLaunchableElements(selection);
if (elements.length > 1)
return useWizard(elements, selection, mode, launcher);
if (elements.length == 0) {
MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(),
"JUnit Launcher", "Could not find a JUnit test class"
);
return true;
}
Object runnable= elements[0];
if (!(runnable instanceof IType)) {
MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(),
"JUnit Launcher", "Could not find a launchable test type"
);
return true;
}
IType[] testTypes= new IType[] {(IType)runnable};
return doLaunch(testTypes, mode, launcher);
}
protected boolean doLaunch(final IType[] testTypes, final String runMode, ILauncher launcher) {
final IType testType= testTypes[0];
fType= testType;
IVMInstall vmInstall;
try {
vmInstall= JavaRuntime.getVMInstall(testType.getJavaProject());
} catch (CoreException e) {
ErrorDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "JUnit Launch", e.getMessage(), e.getStatus());
return true;
}
if (vmInstall == null)
vmInstall= JavaRuntime.getDefaultVMInstall();
if (vmInstall == null) {
MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "JUnit Launch", "No JRE Runtime found");
return true;
}
final IVMRunner vmRunner= vmInstall.getVMRunner(runMode);
final VMRunnerResult returnResult[]= new VMRunnerResult[1];
VMRunnerResult result;
fPort= SocketUtil.findUnusedLocalPort(4000, 5000);
final int finalPort= fPort;
IRunnableWithProgress runnable= new IRunnableWithProgress() {
public void run(IProgressMonitor pm) throws InvocationTargetException {
pm.beginTask("Starting VM ...", IProgressMonitor.UNKNOWN);
try {
VMRunnerConfiguration vmConfig= configureVM(testTypes, finalPort, runMode);
returnResult[0]= vmRunner.run(vmConfig);
} catch (CoreException e) {
throw new InvocationTargetException(e);
}
}
};
try {
new ProgressMonitorDialog(JUnitPlugin.getActiveWorkbenchShell()).run(true, false, runnable);
} catch (InterruptedException e) {
// do nothing - user canceled action
} catch (InvocationTargetException e) {
Throwable te= e.getTargetException();
JUnitPlugin.log(te);
MessageDialog.openError(JUnitPlugin.getActiveWorkbenchShell(), "Could not launch VM", te.getMessage());
return false;
}
result= returnResult[0];
if (result != null && launcher != null) {
// TO DO should use JavaUISourceLocator, but this would break 1.0 compatibility
Launch newLaunch= new Launch(launcher, runMode, testType.getCompilationUnit(), new ProjectSourceLocator(testType.getJavaProject()), result.getProcesses(), result.getDebugTarget());
registerLaunch(newLaunch);
}
fLauncher= launcher;
fRunMode= runMode;
fType= testType;
return true;
}
/*
* @see ILauncherDelegate#getLaunchMemento(Object)
*/
public String getLaunchMemento(Object element) {
if (element instanceof IJavaElement)
return ((IJavaElement)element).getHandleIdentifier();
return null;
}
/*
* @see ILauncherDelegate#getLaunchObject(String)
*/
public Object getLaunchObject(String memento) {
IJavaElement e= JavaCore.create(memento);
if (e.exists())
return e;
return null;
}
public String getRunMode() {
return fRunMode;
}
public int getPort() {
return fPort;
}
public IType getLaunchedType() {
return fType;
}
/**
* Returns a collection of elements this launcher is capable of launching
* in the specified mode based on the given selection. If this launcher cannot launch any
* elements in the current selection, an empty collection or <code>null</code>
* is returned.
*/
public IType[] getLaunchableElements(IStructuredSelection selection) {
try {
ProgressMonitorDialog dialog= new ProgressMonitorDialog(JUnitPlugin.getActiveWorkbenchShell());
return TestSearchEngine.findTargets(dialog, selection.toArray());
} catch (InvocationTargetException e) {
JUnitPlugin.log(e);
} catch (InterruptedException e) {
// user pressed cancel
}
return new IType[0];
}
/**
* Use the wizard to do the launch.
*/
private boolean useWizard(Object[] elements, IStructuredSelection selection, String mode, ILauncher launcher) {
JUnitLaunchWizard wizard= new JUnitLaunchWizard(elements);
wizard.init(launcher, mode, selection);
Shell shell= JUnitPlugin.getActiveWorkbenchShell();
if (shell != null) {
WizardDialog dialog= new WizardDialog(shell, wizard);
int status= dialog.open();
return (status == dialog.OK || status == dialog.CANCEL);
}
return false;
}
/**
* Registers the Process in the Debug View
*/
private void registerLaunch(final ILaunch launch) {
Display.getCurrent().syncExec(new Runnable() {
public void run() {
DebugPlugin.getDefault().getLaunchManager().registerLaunch(launch);
}
});
}
}