package junit.extensions.eclipse.quick.internal.launch; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import junit.extensions.eclipse.quick.internal.ExtensionSupport; import junit.extensions.eclipse.quick.internal.QuickJUnitPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.ui.DebugUITools; import org.eclipse.debug.ui.IDebugModelPresentation; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.internal.junit.launcher.ITestKind; import org.eclipse.jdt.internal.junit.launcher.JUnitLaunchConfigurationConstants; import org.eclipse.jdt.internal.junit.launcher.TestKindRegistry; import org.eclipse.jdt.internal.junit.ui.JUnitMessages; import org.eclipse.jdt.junit.launcher.JUnitLaunchShortcut; import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; import org.eclipse.jdt.ui.JavaElementLabelProvider; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementListSelectionDialog; /** * Copied from super class. */ public class QuickJUnitLaunchShortcut extends JUnitLaunchShortcut { private static final String EMPTY_STRING= ""; public void launch(ISelection selection, String mode) { if (selection instanceof IStructuredSelection) { launch(((IStructuredSelection) selection).toArray(), mode); } else { showNoTestsFoundDialog(); } } private void launch(Object[] elements, String mode) { try { IJavaElement elementToLaunch= null; if (elements.length == 1) { Object selected= elements[0]; if (!(selected instanceof IJavaElement) && selected instanceof IAdaptable) { selected= ((IAdaptable) selected).getAdapter(IJavaElement.class); } if (selected instanceof IJavaElement) { IJavaElement element= (IJavaElement) selected; switch (element.getElementType()) { case IJavaElement.JAVA_PROJECT: case IJavaElement.PACKAGE_FRAGMENT_ROOT: case IJavaElement.PACKAGE_FRAGMENT: case IJavaElement.TYPE: case IJavaElement.METHOD: elementToLaunch= element; break; case IJavaElement.CLASS_FILE: elementToLaunch= ((IClassFile) element).getType(); break; case IJavaElement.COMPILATION_UNIT: elementToLaunch= findTypeToLaunch((ICompilationUnit) element, mode); break; } } } if (elementToLaunch == null) { showNoTestsFoundDialog(); return; } performLaunch(elementToLaunch, mode); } catch (InterruptedException e) { // OK, silently move on } catch (CoreException e) { getPlugin().logSystemError(e, this); } catch (InvocationTargetException e) { getPlugin().logSystemError(e, this); } } private void performLaunch(IJavaElement element, String mode) throws InterruptedException, CoreException { ILaunchConfigurationWorkingCopy temporary= createLaunchConfiguration(element); ILaunchConfiguration config= findExistingLaunchConfiguration(temporary, mode); if (config == null) { // no existing found: create a new one ILaunchConfiguration[] configs= getLaunchManager().getLaunchConfigurations(temporary.getType()); ILaunchConfiguration qjDefault; for(int i = 0; i < configs.length; i++){ if(ExtensionSupport.QUICK_JUNIT_DEFAULT.equals(configs[i].getName())){ qjDefault = configs[i]; Map attributes = qjDefault.getAttributes(); setDefaultAttributes(temporary, attributes); } } config= temporary.doSave(); } DebugUITools.launch(config, mode); } private static final Set KEY_SET = new HashSet(); static { KEY_SET.add(IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS); } private void setDefaultAttributes( ILaunchConfigurationWorkingCopy temporary, Map attributes) { Iterator itr = attributes.keySet().iterator(); for(Object obj = null;itr.hasNext();){ obj = itr.next(); String key = (String)obj; boolean contains = false; try{ contains = attributes.containsKey(key); }catch(NullPointerException e){ continue; } if(contains && KEY_SET.contains(key)){ Object object = attributes.get(key); if(object != null){ String value = object.toString(); temporary.setAttribute(key, value); } } } } private ILaunchConfiguration findExistingLaunchConfiguration(ILaunchConfigurationWorkingCopy temporary, String mode) throws InterruptedException, CoreException { List candidateConfigs= findExistingLaunchConfigurations(temporary); // If there are no existing configs associated with the IType, create // one. // If there is exactly one config associated with the IType, return it. // Otherwise, if there is more than one config associated with the // IType, prompt the // user to choose one. int candidateCount= candidateConfigs.size(); if (candidateCount == 0) { return null; } else if (candidateCount == 1) { return (ILaunchConfiguration) candidateConfigs.get(0); } else { // Prompt the user to choose a config. A null result means the user // cancelled the dialog, in which case this method returns null, // since cancelling the dialog should also cancel launching // anything. ILaunchConfiguration config= chooseConfiguration(candidateConfigs, mode); if (config != null) { return config; } } return null; } private ILaunchConfiguration chooseConfiguration(List configList, String mode) throws InterruptedException { IDebugModelPresentation labelProvider= DebugUITools.newDebugModelPresentation(); ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider); dialog.setElements(configList.toArray()); dialog.setTitle(JUnitMessages.JUnitLaunchShortcut_message_selectConfiguration); if (mode.equals(ILaunchManager.DEBUG_MODE)) { dialog.setMessage(JUnitMessages.JUnitLaunchShortcut_message_selectDebugConfiguration); } else { dialog.setMessage(JUnitMessages.JUnitLaunchShortcut_message_selectRunConfiguration); } dialog.setMultipleSelection(false); int result= dialog.open(); if (result == Window.OK) { return (ILaunchConfiguration) dialog.getFirstResult(); } throw new InterruptedException(); // cancelled by user } private List findExistingLaunchConfigurations(ILaunchConfigurationWorkingCopy temporary) throws CoreException { ILaunchConfigurationType configType= temporary.getType(); ILaunchConfiguration[] configs= getLaunchManager().getLaunchConfigurations(configType); String[] attributeToCompare= getAttributeNamesToCompare(); ArrayList candidateConfigs= new ArrayList(configs.length); for (int i= 0; i < configs.length; i++) { ILaunchConfiguration config= configs[i]; if (hasSameAttributes(config, temporary, attributeToCompare)) { candidateConfigs.add(config); } } return candidateConfigs; } protected String[] getAttributeNamesToCompare() { return new String[] { IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, JUnitLaunchConfigurationConstants.ATTR_TEST_CONTAINER, IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, JUnitLaunchConfigurationConstants.ATTR_TEST_METHOD_NAME }; } private static boolean hasSameAttributes(ILaunchConfiguration config1, ILaunchConfiguration config2, String[] attributeToCompare) { try { for (int i= 0; i < attributeToCompare.length; i++) { String val1= config1.getAttribute(attributeToCompare[i], EMPTY_STRING); String val2= config2.getAttribute(attributeToCompare[i], EMPTY_STRING); if (!val1.equals(val2)) { return false; } } return true; } catch (CoreException e) { // ignore access problems here, return false } return false; } private IType findTypeToLaunch(ICompilationUnit cu, String mode) throws InterruptedException, InvocationTargetException { IType[] types= findTypesToLaunch(cu); if (types.length == 0) { return null; } else if (types.length > 1) { return chooseType(types, mode); } return types[0]; } private IType chooseType(IType[] types, String mode) throws InterruptedException { ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_POST_QUALIFIED)); dialog.setElements(types); dialog.setTitle(JUnitMessages.JUnitLaunchShortcut_dialog_title2); if (mode.equals(ILaunchManager.DEBUG_MODE)) { dialog.setMessage(JUnitMessages.JUnitLaunchShortcut_message_selectTestToDebug); } else { dialog.setMessage(JUnitMessages.JUnitLaunchShortcut_message_selectTestToRun); } dialog.setMultipleSelection(false); if (dialog.open() == Window.OK) { return (IType) dialog.getFirstResult(); } throw new InterruptedException(); // cancelled by user } private IType[] findTypesToLaunch(final ICompilationUnit cu) throws InterruptedException, InvocationTargetException { final ITestKind testKind= TestKindRegistry.getContainerTestKind(cu); final Set result = new HashSet(); IRunnableWithProgress runnable= new IRunnableWithProgress() { public void run(IProgressMonitor pm) throws InterruptedException, InvocationTargetException { try { testKind.getFinder().findTestsInContainer(cu, result, pm); } catch (CoreException e) { throw new InvocationTargetException(e); } } }; PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(false, false, runnable); return (IType[]) result.toArray(new IType[]{}); } private void showNoTestsFoundDialog() { MessageDialog.openInformation(getShell(), JUnitMessages.JUnitLaunchShortcut_dialog_title, JUnitMessages.JUnitLaunchShortcut_message_notests); } private Shell getShell() { IWorkbenchWindow workBenchWindow = getWorkbenchWindow(); return getActiveShell(workBenchWindow); } private IWorkbenchWindow getWorkbenchWindow() { return PlatformUI.getWorkbench().getActiveWorkbenchWindow(); } private Shell getActiveShell(IWorkbenchWindow workBenchWindow) { if (workBenchWindow == null) return null; return workBenchWindow.getShell(); } private static ILaunchManager getLaunchManager() { return QuickJUnitPlugin.getDefault().getLaunchManager(); } private QuickJUnitPlugin getPlugin() { return QuickJUnitPlugin.getDefault(); } }