| /******************************************************************************* |
| * Copyright (c) 2012 Sierra Wireless 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: |
| * Sierra Wireless - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ldt.debug.ui.internal.launchconfiguration.local; |
| |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| 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.internal.ui.DebugUIPlugin; |
| import org.eclipse.debug.internal.ui.launchConfigurations.LaunchHistory; |
| import org.eclipse.debug.ui.DebugUITools; |
| import org.eclipse.debug.ui.ILaunchGroup; |
| import org.eclipse.dltk.compiler.env.IModuleSource; |
| import org.eclipse.dltk.compiler.util.Util; |
| import org.eclipse.dltk.core.DLTKCore; |
| import org.eclipse.dltk.core.IModelElement; |
| import org.eclipse.dltk.core.IParent; |
| import org.eclipse.dltk.core.IScriptFolder; |
| import org.eclipse.dltk.core.IScriptProject; |
| import org.eclipse.dltk.core.ISourceModule; |
| import org.eclipse.dltk.core.ModelException; |
| import org.eclipse.dltk.internal.core.ProjectFragment; |
| import org.eclipse.dltk.internal.debug.ui.launcher.AbstractScriptLaunchShortcut; |
| import org.eclipse.dltk.launching.IInterpreterInstall; |
| import org.eclipse.dltk.launching.LaunchingMessages; |
| import org.eclipse.dltk.launching.ScriptLaunchConfigurationConstants; |
| import org.eclipse.dltk.launching.ScriptRuntime; |
| import org.eclipse.dltk.launching.process.ScriptRuntimeProcessFactory; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.ldt.core.LuaConstants; |
| import org.eclipse.ldt.core.LuaNature; |
| import org.eclipse.ldt.core.LuaUtils; |
| import org.eclipse.ldt.core.internal.buildpath.LuaExecutionEnvironmentBuildpathUtil; |
| import org.eclipse.ldt.debug.core.internal.LuaDebugConstants; |
| import org.eclipse.ldt.debug.core.interpreter.LuaInterpreterUtil; |
| import org.eclipse.ldt.debug.ui.internal.Activator; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.ui.PlatformUI; |
| |
| /** |
| * Run As strategy:<br> |
| * launch the latest launch config for the selection<br> |
| * if not found : <br> |
| * 1) A file is selected <br> |
| * -> create a new one <br> |
| * 2) A folder is selected <br> |
| * -> the folder have only 1 file -> do 1)<br> |
| * -> the folder contains several files -> prompt the one to be selected, then do 1)<br> |
| * 3) A project is selected<br> |
| * -> there is a main module -> do 1)<br> |
| * -> there is no main module -> do 2)<br> |
| */ |
| @SuppressWarnings("restriction") |
| public class LuaApplicationLaunchShortcut extends AbstractScriptLaunchShortcut { |
| |
| @Override |
| protected ILaunchConfigurationType getConfigurationType() { |
| return DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(LuaDebugConstants.LOCAL_LAUNCH_CONFIGURATION_ID); |
| } |
| |
| @Override |
| protected String getNatureId() { |
| return LuaNature.ID; |
| } |
| |
| @Override |
| public void searchAndLaunch(Object[] search, String mode, String selectMessage, String emptyMessage) { |
| |
| // As the Lua Application Run As menu is enable only when one item is selected (see extension point) |
| // the following code just take in account the first element |
| Object selection = search[0]; |
| |
| // configuration to launch : |
| ILaunchConfiguration config = null; |
| |
| // find existing |
| config = findExistingLaunchConfiguration(selection, mode); |
| |
| // not found create one |
| if (config == null) |
| config = createLaunchConfiguration(selection); |
| |
| // Launch |
| if (config != null) |
| DebugUITools.launch(config, mode); |
| } |
| |
| private ILaunchConfiguration createLaunchConfiguration(Object selection) { |
| |
| // script selection |
| if (selection instanceof IFile) { |
| return createLaunchConfiguration((IFile) selection); |
| } else if (selection instanceof ISourceModule) { |
| try { |
| IResource correspondingResource = ((ISourceModule) selection).getCorrespondingResource(); |
| if (correspondingResource instanceof IFile) |
| return createLaunchConfiguration((IFile) correspondingResource); |
| } catch (ModelException e) { |
| Activator.logError(NLS.bind("Unable to get corresponding resource for module {0}", selection), e); //$NON-NLS-1$ |
| return null; |
| } |
| } |
| // source folder selection |
| else if (selection instanceof IFolder) { |
| IModelElement sourcefolder = DLTKCore.create((IFolder) selection); |
| if (sourcefolder instanceof IScriptFolder) |
| return createLaunchConfiguration((IScriptFolder) sourcefolder); |
| } else if (selection instanceof IScriptFolder) { |
| return createLaunchConfiguration((IScriptFolder) selection); |
| } |
| // project selection |
| else if (selection instanceof IProject) { |
| IScriptProject project = DLTKCore.create((IProject) selection); |
| if (project != null) |
| return createLaunchConfiguration(project); |
| } else if (selection instanceof ProjectFragment) { |
| IScriptProject scriptProject = ((ProjectFragment) selection).getScriptProject(); |
| if (scriptProject != null) |
| return createLaunchConfiguration(scriptProject); |
| } else if (selection instanceof IScriptProject) { |
| return createLaunchConfiguration((IScriptProject) selection); |
| } |
| return null; |
| } |
| |
| public ILaunchConfiguration createLaunchConfiguration(IFile script) { |
| ILaunchConfiguration config = null; |
| ILaunchConfigurationWorkingCopy wc = null; |
| try { |
| ILaunchConfigurationType configType = getConfigurationType(); |
| |
| // custom launch conf name |
| String fileNameWithoutExtension = script.getLocation().removeFileExtension().lastSegment(); |
| String configNamePrefix = MessageFormat.format("{0}_{1}", script.getProject().getName(), fileNameWithoutExtension); //$NON-NLS-1$ |
| |
| wc = configType.newInstance(null, getLaunchManager().generateLaunchConfigurationName(configNamePrefix)); |
| wc.setAttribute(ScriptLaunchConfigurationConstants.ATTR_SCRIPT_NATURE, getNatureId()); |
| wc.setAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, script.getProject().getName()); |
| wc.setAttribute(ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME, script.getProjectRelativePath().toPortableString()); |
| wc.setAttribute(DebugPlugin.ATTR_PROCESS_FACTORY_ID, ScriptRuntimeProcessFactory.PROCESS_FACTORY_ID); |
| wc.setAttribute(ScriptLaunchConfigurationConstants.ATTR_DEBUG_CONSOLE, false); |
| |
| // Manage interpreters. |
| IInterpreterInstall guessInterpreter = findBestInterpreter(script); |
| if (guessInterpreter != null) { |
| IPath interpreterContainerPath = ScriptRuntime.newInterpreterContainerPath(guessInterpreter); |
| if (interpreterContainerPath != null) |
| wc.setAttribute(ScriptLaunchConfigurationConstants.ATTR_CONTAINER_PATH, interpreterContainerPath.toPortableString()); |
| } |
| |
| wc.setMappedResources(new IResource[] { script }); |
| config = wc.doSave(); |
| } catch (CoreException e) { |
| Activator.logError("Unable to create a launch configuration from a LaunchShortcut", e); //$NON-NLS-1$ |
| } |
| return config; |
| } |
| |
| public IInterpreterInstall findBestInterpreter(IFile script) { |
| IProject project = script.getProject(); |
| if (project == null) |
| return null; |
| |
| IScriptProject scriptProject = DLTKCore.create(project); |
| if (scriptProject == null || !LuaUtils.isLuaProject(project)) |
| return null; |
| |
| IPath eePath = LuaUtils.getLuaExecutionEnvironmentPath(scriptProject); |
| if (eePath == null) |
| return null; |
| |
| String eeid = LuaExecutionEnvironmentBuildpathUtil.getEEID(eePath); |
| String eeVersion = LuaExecutionEnvironmentBuildpathUtil.getEEVersion(eePath); |
| if (eeid == null || eeVersion == null) |
| return null; |
| |
| // if this project has an execution environment |
| // check if the default one is compatible |
| IInterpreterInstall defaultInterpreterInstall = LuaInterpreterUtil.getDefaultInterpreter(); |
| if (defaultInterpreterInstall != null && LuaInterpreterUtil.isExecutionEnvironmentCompatible(defaultInterpreterInstall, eeid, eeVersion)) |
| return defaultInterpreterInstall; |
| |
| // else check with other interpreters |
| IInterpreterInstall embeddedinterpreter = null; |
| for (IInterpreterInstall interpreter : LuaInterpreterUtil.getInterpreters()) { |
| if (LuaInterpreterUtil.isExecutionEnvironmentCompatible(interpreter, eeid, eeVersion)) { |
| // we give priority to non embedded interpreter |
| if (LuaInterpreterUtil.isEmbedded(interpreter)) |
| embeddedinterpreter = interpreter; |
| else |
| return interpreter; |
| } |
| } |
| return embeddedinterpreter; |
| } |
| |
| public ILaunchConfiguration createLaunchConfiguration(IParent sourcecontainer) { |
| // Search scripts contains in this container |
| IResource[] scripts = null; |
| try { |
| scripts = findScripts(new Object[] { sourcecontainer }, PlatformUI.getWorkbench().getProgressService()); |
| } catch (InterruptedException e) { |
| return null; |
| } catch (CoreException e) { |
| MessageDialog.openError(getShell(), LaunchingMessages.ScriptLaunchShortcut_0, e.getMessage()); |
| return null; |
| } |
| |
| IResource script; |
| if (scripts.length == 0) { |
| // no file in folder |
| MessageDialog.openError(getShell(), LaunchingMessages.ScriptLaunchShortcut_1, getSelectionEmptyMessage()); |
| } else if (scripts.length == 1) { |
| // create a new one for this script |
| return createLaunchConfiguration(scripts[0]); |
| } else if (scripts.length > 1) { |
| // prompt user to choose a script |
| script = chooseScript(scripts, getScriptSelectionTitle()); |
| if (script != null) { |
| return createLaunchConfiguration(scripts[0]); |
| } |
| } |
| return null; |
| } |
| |
| public ILaunchConfiguration createLaunchConfiguration(IScriptProject project) { |
| // search a main file |
| String defaultModuleName = new Path(LuaConstants.DEFAULT_MAIN_FILE).removeFileExtension().toString(); |
| IModuleSource mainModule = LuaUtils.getModuleSource(defaultModuleName, project); |
| if (mainModule != null) { |
| try { |
| return createLaunchConfiguration(mainModule.getModelElement().getCorrespondingResource()); |
| } catch (ModelException e) { |
| Activator.logWarning("Unable to find ressource corresponding to main module", e); //$NON-NLS-1$ |
| } |
| } |
| |
| // if not found do the same as sourcefolder |
| return createLaunchConfiguration((IParent) project); |
| } |
| |
| /** |
| * find the last launch configuration for this container |
| */ |
| private ILaunchConfiguration findExistingLaunchConfiguration(Object container, String launchMode) { |
| try { |
| // get all existing config |
| List<ILaunchConfiguration> candidateConfigs = retreiveLaunchConfiguration(launchMode); |
| |
| // search the first which match for this container |
| candidateConfigs = filterConfig(container, candidateConfigs); |
| |
| if (!candidateConfigs.isEmpty()) { |
| return candidateConfigs.get(0); |
| } |
| } catch (CoreException e) { |
| Activator.logWarning("Unable to retrieve existing launch configuration.", e); //$NON-NLS-1$ |
| } catch (InterruptedException e) { |
| return null; |
| } |
| |
| return null; |
| } |
| |
| /** |
| * get all existing launch configuration for the current type and launch mode sorted by favorites then history. |
| */ |
| private List<ILaunchConfiguration> retreiveLaunchConfiguration(String launchMode) throws CoreException { |
| ILaunchGroup group = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchGroup(getConfigurationType(), launchMode); |
| LaunchHistory history = DebugUIPlugin.getDefault().getLaunchConfigurationManager().getLaunchHistory(group.getIdentifier()); |
| |
| List<ILaunchConfiguration> candidateConfigs = new ArrayList<ILaunchConfiguration>(); |
| candidateConfigs.addAll(Arrays.asList(history.getFavorites())); |
| candidateConfigs.addAll(Arrays.asList(history.getHistory())); |
| |
| // if no history for our resource, let filter existing configs |
| if (candidateConfigs.isEmpty()) { |
| candidateConfigs.addAll(Arrays.asList(DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurations(getConfigurationType()))); |
| } |
| return candidateConfigs; |
| } |
| |
| /** |
| * search the config in candidateConfigs list which match for this selection. <br> |
| * |
| * see {@link org.eclipse.dltk.internal.debug.ui.launcher.AbstractScriptLaunchShortcut.getScriptResources(Object[], IProgressMonitor)} |
| */ |
| private List<ILaunchConfiguration> filterConfig(Object selection, List<ILaunchConfiguration> candidateConfigs) |
| throws InterruptedException, CoreException { |
| IResource[] scripts = findScripts(new Object[] { selection }, PlatformUI.getWorkbench().getProgressService()); |
| return filterConfig(Arrays.asList(scripts), candidateConfigs); |
| } |
| |
| /** |
| * search the config in candidateConfigs list which match for this list of scripts. |
| */ |
| private List<ILaunchConfiguration> filterConfig(List<IResource> scripts, List<ILaunchConfiguration> configs) throws CoreException { |
| List<ILaunchConfiguration> candidateConfigs = new ArrayList<ILaunchConfiguration>(); |
| for (ILaunchConfiguration config : configs) { |
| for (IResource script : scripts) { |
| if (config.getAttribute(ScriptLaunchConfigurationConstants.ATTR_MAIN_SCRIPT_NAME, Util.EMPTY_STRING) |
| .equals(script.getProjectRelativePath().toString()) |
| && config.getAttribute(ScriptLaunchConfigurationConstants.ATTR_PROJECT_NAME, Util.EMPTY_STRING) |
| .equals(script.getProject().getName()) |
| && config.getType().equals(getConfigurationType())) { |
| candidateConfigs.add(config); |
| } |
| } |
| } |
| return candidateConfigs; |
| } |
| |
| @Override |
| protected void launch(final IResource script, final String mode) { |
| searchAndLaunch(new Object[] { script }, mode, null, null); |
| } |
| |
| /** |
| * @Deprecated use createLaunchConfiguration |
| */ |
| @Override |
| @Deprecated |
| protected ILaunchConfiguration createConfiguration(IResource script) { |
| return super.createConfiguration(script); |
| } |
| } |