package com.aptana.ruby.debug.ui.launcher; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.Status; 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.ILaunchShortcut; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IFileEditorInput; import com.aptana.core.logging.IdeLog; import com.aptana.core.util.StringUtil; import com.aptana.ruby.debug.core.launching.IRubyLaunchConfigurationConstants; import com.aptana.ruby.debug.ui.RubyDebugUIPlugin; public class RubyApplicationShortcut implements ILaunchShortcut { public void launch(ISelection selection, String mode) { if (selection instanceof IStructuredSelection) { try { IStructuredSelection structured = (IStructuredSelection) selection; Object first = structured.getFirstElement(); if (first instanceof IFile) { doLaunch((IFile) first, mode); } else if (first instanceof IAdaptable) { IAdaptable adapt = (IAdaptable) first; first = adapt.getAdapter(IResource.class); if (first instanceof IFile) { doLaunch((IFile) first, mode); } } } catch (CoreException e) { IdeLog.logError(RubyDebugUIPlugin.getDefault(), e); } } } protected void doLaunch(IFile rubyElement, String mode) throws CoreException { ILaunchConfiguration config = findOrCreateLaunchConfiguration(rubyElement, mode); if (config != null) { DebugUITools.launch(config, mode); } } public void launch(IEditorPart editor, String mode) { IEditorInput input = editor.getEditorInput(); if (input == null) { IdeLog.logError(RubyDebugUIPlugin.getDefault(), "Could not retrieve input from editor: " + editor.getTitle()); //$NON-NLS-1$ return; } if (input instanceof IFileEditorInput) { IFileEditorInput fileInput = (IFileEditorInput) input; IFile file = fileInput.getFile(); try { doLaunch(file, mode); } catch (CoreException e) { IdeLog.logError(RubyDebugUIPlugin.getDefault(), e); } } // TODO Allow launching from URIs as long as it's a file we can reach! } protected ILaunchConfiguration findOrCreateLaunchConfiguration(IFile rubyFile, String mode) throws CoreException { ILaunchConfigurationType configType = getRubyLaunchConfigType(); ILaunchConfiguration[] configs = getLaunchManager().getLaunchConfigurations(configType); List<ILaunchConfiguration> candidateConfigs = new ArrayList<ILaunchConfiguration>(configs.length); for (ILaunchConfiguration config : configs) { boolean absoluteFilenamesMatch = config.getAttribute(IRubyLaunchConfigurationConstants.ATTR_FILE_NAME, StringUtil.EMPTY).equals(rubyFile.getLocation().toOSString()); if (absoluteFilenamesMatch) { candidateConfigs.add(config); } } switch (candidateConfigs.size()) { case 0: return createConfiguration(rubyFile); case 1: return candidateConfigs.get(0); default: Status status = new Status(Status.WARNING, RubyDebugUIPlugin.getPluginId(), 0, "Multiple configurations match", null); //$NON-NLS-1$ throw new CoreException(status); } } protected ILaunchConfiguration createConfiguration(IFile rubyFile) { ILaunchConfiguration config = null; try { ILaunchConfigurationType configType = getRubyLaunchConfigType(); ILaunchConfigurationWorkingCopy wc = configType.newInstance(null, getLaunchManager() .generateLaunchConfigurationName(rubyFile.getName())); // wc.setAttribute(IRubyLaunchConfigurationConstants.ATTR_PROJECT_NAME, rubyFile.getProject().getName()); wc.setAttribute(IRubyLaunchConfigurationConstants.ATTR_FILE_NAME, rubyFile.getLocation().toOSString()); wc.setAttribute(IRubyLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY, RubyApplicationShortcut.getDefaultWorkingDirectory(rubyFile)); wc.setAttribute(ILaunchConfiguration.ATTR_SOURCE_LOCATOR_ID, IRubyLaunchConfigurationConstants.ID_RUBY_SOURCE_LOCATOR); config = wc.doSave(); } catch (CoreException ce) { IdeLog.logError(RubyDebugUIPlugin.getDefault(), ce); } return config; } protected ILaunchConfigurationType getRubyLaunchConfigType() { return getLaunchManager().getLaunchConfigurationType(IRubyLaunchConfigurationConstants.ID_RUBY_APPLICATION); } protected ILaunchManager getLaunchManager() { return DebugPlugin.getDefault().getLaunchManager(); } protected static String getDefaultWorkingDirectory(IFile file) { // FIXME Maybe just always assume project root? // Grab the current file's container if (file.getParent() != null && file.getParent().exists()) { return file.getParent().getLocation().toOSString(); } // Something wacky happened, try the current project... if (file.getProject() != null && file.getProject().exists()) { return file.getProject().getLocation().toOSString(); } // Weird! Try the workspace root return ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString(); } }