| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui.launcher; |
| |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.debug.core.DebugPlugin; |
| 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.debug.ui.ILaunchFilter; |
| import org.eclipse.debug.ui.ILaunchShortcut; |
| 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.core.JavaCore; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.debug.ui.JavaUISourceLocator; |
| import org.eclipse.jdt.internal.corext.util.JavaModelUtil; |
| import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; |
| import org.eclipse.jdt.internal.debug.ui.console.StringMatcher; |
| import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.dialogs.ElementListSelectionDialog; |
| |
| /** |
| * Performs single click launching for local Java applications. |
| */ |
| public class JavaApplicationLaunchShortcut implements ILaunchShortcut, ILaunchFilter { |
| |
| /** |
| * @param search the java elements to search for a main type |
| * @param mode the mode to launch in |
| * @param editor activated on an editor (or from a selection in a viewer) |
| */ |
| public void searchAndLaunch(Object[] search, String mode, boolean editor) { |
| IType[] types = null; |
| if (search != null) { |
| try { |
| ProgressMonitorDialog dialog = new ProgressMonitorDialog(getShell()); |
| types = MainMethodFinder.findTargets(dialog, search); |
| } catch (InterruptedException e) { |
| return; |
| } catch (InvocationTargetException e) { |
| MessageDialog.openError(getShell(), LauncherMessages.getString("JavaApplicationAction.Launch_failed_7"), e.getMessage()); //$NON-NLS-1$ |
| return; |
| } |
| IType type = null; |
| if (types.length == 0) { |
| String message = null; |
| if (editor) { |
| message = LauncherMessages.getString("JavaApplicationLaunchShortcut.The_active_editor_does_not_contain_a_main_type._1"); //$NON-NLS-1$ |
| } else { |
| message = LauncherMessages.getString("JavaApplicationLaunchShortcut.The_selection_does_not_contain_a_main_type._2"); //$NON-NLS-1$ |
| } |
| MessageDialog.openError(getShell(), LauncherMessages.getString("JavaApplicationAction.Launch_failed_7"), message); //$NON-NLS-1$ |
| } else if (types.length > 1) { |
| type = chooseType(types, mode); |
| } else { |
| type = types[0]; |
| } |
| if (type != null) { |
| launch(type, mode); |
| } |
| } |
| |
| } |
| |
| /** |
| * Prompts the user to select a type |
| * |
| * @return the selected type or <code>null</code> if none. |
| */ |
| protected IType chooseType(IType[] types, String mode) { |
| MainTypeSelectionDialog dialog= new MainTypeSelectionDialog(getShell(), types); |
| if (mode.equals(ILaunchManager.DEBUG_MODE)) { |
| dialog.setTitle(LauncherMessages.getString("JavaApplicationAction.Type_Selection_Debug")); //$NON-NLS-1$ |
| } else { |
| dialog.setTitle(LauncherMessages.getString("JavaApplicationAction.Type_Selection_Run")); //$NON-NLS-1$ |
| } |
| dialog.setMultipleSelection(false); |
| if (dialog.open() == Window.OK) { |
| return (IType)dialog.getFirstResult(); |
| } |
| return null; |
| } |
| |
| /** |
| * Launches a configuration for the given type |
| */ |
| protected void launch(IType type, String mode) { |
| ILaunchConfiguration config = findLaunchConfiguration(type, mode); |
| if (config != null) { |
| DebugUITools.launch(config, mode); |
| } |
| } |
| |
| /** |
| * Locate a configuration to relaunch for the given type. If one cannot be found, create one. |
| * |
| * @return a re-useable config or <code>null</code> if none |
| */ |
| protected ILaunchConfiguration findLaunchConfiguration(IType type, String mode) { |
| ILaunchConfigurationType configType = getJavaLaunchConfigType(); |
| List candidateConfigs = Collections.EMPTY_LIST; |
| try { |
| ILaunchConfiguration[] configs = DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(configType); |
| candidateConfigs = new ArrayList(configs.length); |
| for (int i = 0; i < configs.length; i++) { |
| ILaunchConfiguration config = configs[i]; |
| if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, "").equals(type.getFullyQualifiedName())) { //$NON-NLS-1$ |
| if (config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, "").equals(type.getJavaProject().getElementName())) { //$NON-NLS-1$ |
| candidateConfigs.add(config); |
| } |
| } |
| } |
| } catch (CoreException e) { |
| JDIDebugUIPlugin.log(e); |
| } |
| |
| // 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 < 1) { |
| return createConfiguration(type); |
| } 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; |
| } |
| |
| /** |
| * Show a selection dialog that allows the user to choose one of the specified |
| * launch configurations. Return the chosen config, or <code>null</code> if the |
| * user cancelled the dialog. |
| */ |
| protected ILaunchConfiguration chooseConfiguration(List configList, String mode) { |
| IDebugModelPresentation labelProvider = DebugUITools.newDebugModelPresentation(); |
| ElementListSelectionDialog dialog= new ElementListSelectionDialog(getShell(), labelProvider); |
| dialog.setElements(configList.toArray()); |
| dialog.setTitle(LauncherMessages.getString("JavaApplicationAction.Launch_Configuration_Selection_1")); //$NON-NLS-1$ |
| if (mode.equals(ILaunchManager.DEBUG_MODE)) { |
| dialog.setMessage(LauncherMessages.getString("JavaApplicationAction.Choose_a_launch_configuration_to_debug_2")); //$NON-NLS-1$ |
| } else { |
| dialog.setMessage(LauncherMessages.getString("JavaApplicationAction.Choose_a_launch_configuration_to_run_3")); //$NON-NLS-1$ |
| } |
| dialog.setMultipleSelection(false); |
| int result = dialog.open(); |
| labelProvider.dispose(); |
| if (result == Window.OK) { |
| return (ILaunchConfiguration) dialog.getFirstResult(); |
| } |
| return null; |
| } |
| |
| /** |
| * Create & return a new configuration based on the specified <code>IType</code>. |
| */ |
| protected ILaunchConfiguration createConfiguration(IType type) { |
| ILaunchConfiguration config = null; |
| ILaunchConfigurationWorkingCopy wc = null; |
| try { |
| ILaunchConfigurationType configType = getJavaLaunchConfigType(); |
| wc = configType.newInstance(null, getLaunchManager().generateUniqueLaunchConfigurationNameFrom(type.getElementName())); |
| } catch (CoreException exception) { |
| reportCreatingConfiguration(exception); |
| return null; |
| } |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, type.getFullyQualifiedName()); |
| wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, type.getJavaProject().getElementName()); |
| wc.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, JavaUISourceLocator.ID_PROMPTING_JAVA_SOURCE_LOCATOR); |
| try { |
| config = wc.doSave(); |
| } catch (CoreException exception) { |
| reportCreatingConfiguration(exception); |
| } |
| return config; |
| } |
| |
| protected void reportCreatingConfiguration(final CoreException exception) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| ErrorDialog.openError(getShell(), LauncherMessages.getString("JavaApplicationLaunchShortcut.Error_Launching_1"), LauncherMessages.getString("JavaApplicationLaunchShortcut.Exception"), exception.getStatus()); //new Status(IStatus.ERROR, JDIDebugUIPlugin.getUniqueIdentifier(), IStatus.ERROR, exception.getMessage(), exception)); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| }); |
| } |
| |
| /** |
| * Returns the local java launch config type |
| */ |
| protected ILaunchConfigurationType getJavaLaunchConfigType() { |
| return getLaunchManager().getLaunchConfigurationType(IJavaLaunchConfigurationConstants.ID_JAVA_APPLICATION); |
| } |
| |
| protected ILaunchManager getLaunchManager() { |
| return DebugPlugin.getDefault().getLaunchManager(); |
| } |
| |
| /** |
| * Convenience method to get the window that owns this action's Shell. |
| */ |
| protected Shell getShell() { |
| return JDIDebugUIPlugin.getActiveWorkbenchShell(); |
| } |
| |
| /** |
| * @see ILaunchShortcut#launch(IEditorPart, String) |
| */ |
| public void launch(IEditorPart editor, String mode) { |
| IEditorInput input = editor.getEditorInput(); |
| IJavaElement je = (IJavaElement) input.getAdapter(IJavaElement.class); |
| if (je != null) { |
| searchAndLaunch(new Object[] {je}, mode, true); |
| } else { |
| MessageDialog.openError(getShell(), LauncherMessages.getString("JavaApplicationAction.Launch_failed_7"), LauncherMessages.getString("JavaApplicationLaunchShortcut.The_active_editor_does_not_contain_a_main_type._1")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| } |
| |
| /** |
| * @see ILaunchShortcut#launch(ISelection, String) |
| */ |
| public void launch(ISelection selection, String mode) { |
| if (selection instanceof IStructuredSelection) { |
| searchAndLaunch(((IStructuredSelection)selection).toArray(), mode, false); |
| } else { |
| MessageDialog.openError(getShell(), LauncherMessages.getString("JavaApplicationAction.Launch_failed_7"), LauncherMessages.getString("JavaApplicationLaunchShortcut.The_selection_does_not_contain_a_main_type._2")); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ui.IActionFilter#testAttribute(java.lang.Object, java.lang.String, java.lang.String) |
| */ |
| public boolean testAttribute(IResource target, String name, String value) { |
| if ("ContextualLaunchActionFilter".equals(name)) { //$NON-NLS-1$ |
| return hasMain(target); |
| } else if ("NameMatches".equals(name)) { //$NON-NLS-1$ |
| return nameMatches(target, value); |
| } |
| return false; |
| } |
| |
| /** |
| * Test if the name of the target resource matches a pattern. |
| * |
| * @param target selected resource from workspace |
| * @param value regular expression pattern to test |
| * @return true if the pattern matches the resource name, false otherwise |
| */ |
| private boolean nameMatches(IResource target, String regexp) { |
| String filename = target.getName(); |
| StringMatcher sm = new StringMatcher(regexp, true, false); |
| return sm.match(filename); |
| } |
| |
| /** |
| * Look for a Java main() method in the specified resource. |
| * @return true if the target resource has a <code>main</code> method, |
| * <code>false</code> otherwise. |
| */ |
| private boolean hasMain(IResource target) { |
| if (target != null) { |
| IJavaElement element = JavaCore.create(target); |
| if (element instanceof ICompilationUnit) { |
| ICompilationUnit cu = (ICompilationUnit) element; |
| IType mainType= cu.getType(Signature.getQualifier(cu.getElementName())); |
| try { |
| if (mainType.exists() && JavaModelUtil.hasMainMethod(mainType)) { |
| return true; |
| } |
| } catch (JavaModelException e) { |
| return false; |
| } |
| } else if (element instanceof IClassFile) { |
| IType mainType; |
| try { |
| mainType = ((IClassFile)element).getType(); |
| if (JavaModelUtil.hasMainMethod(mainType)) { |
| return true; |
| } |
| } catch (JavaModelException e) { |
| return false; |
| } |
| } |
| } |
| return false; |
| } |
| } |