PageRenderTime 39ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/eclipse-rse-3.4/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchUtilities.java

#
Java | 304 lines | 165 code | 49 blank | 90 comment | 27 complexity | efe1ee48f08e063c2ca8861028734108 MD5 | raw file
  1. /***************************************************************************************************
  2. * Copyright (c) 2008, 2010 Mirko Raner and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Mirko Raner - [196337] Adapted from org.eclipse.ui.externaltools/ExternalToolsUtil
  10. * Mirko Raner - [314195] vi editor unusable in tcsh local terminal on Linux RHEL4
  11. **************************************************************************************************/
  12. package org.eclipse.tm.internal.terminal.local.launch;
  13. import java.io.File;
  14. import java.text.Format;
  15. import java.text.MessageFormat;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.Map;
  19. import org.eclipse.core.runtime.CoreException;
  20. import org.eclipse.core.runtime.IPath;
  21. import org.eclipse.core.runtime.IStatus;
  22. import org.eclipse.core.runtime.Path;
  23. import org.eclipse.core.runtime.Platform;
  24. import org.eclipse.core.runtime.Status;
  25. import org.eclipse.core.variables.IStringVariableManager;
  26. import org.eclipse.core.variables.VariablesPlugin;
  27. import org.eclipse.debug.core.DebugPlugin;
  28. import org.eclipse.debug.core.ILaunchConfiguration;
  29. import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
  30. import org.eclipse.debug.core.ILaunchManager;
  31. import org.eclipse.debug.ui.DebugUITools;
  32. import org.eclipse.osgi.util.NLS;
  33. import org.eclipse.swt.graphics.Image;
  34. import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator;
  35. import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages;
  36. import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities;
  37. import org.eclipse.tm.internal.terminal.provisional.api.Logger;
  38. /**
  39. * The class {@link LocalTerminalLaunchUtilities} provides some utility methods that are used by the
  40. * {@link LocalTerminalLaunchDelegate}. The class is based on the <code>ExternalToolsUtil</code>
  41. * class in the <code>org.eclipse.ui.externaltools</code> plug-in. This code had to be duplicated
  42. * because the original class is not part of the public API of its plug-in.
  43. *
  44. * @author Mirko Raner and others
  45. * @version $Revision: 1.5 $
  46. */
  47. public class LocalTerminalLaunchUtilities {
  48. /** The launch configuration attribute for the local echo setting. */
  49. public final static String ATTR_LOCAL_ECHO = LocalTerminalActivator.PLUGIN_ID +
  50. ".echo"; //$NON-NLS-1$
  51. /** The launch configuration attribute for the Ctrl-C/SIGINT setting. */
  52. public final static String ATTR_CTRL_C = LocalTerminalActivator.PLUGIN_ID +
  53. ".sigint"; //$NON-NLS-1$
  54. /** The launch configuration attribute for the line terminator setting. */
  55. public final static String ATTR_LINE_SEPARATOR = LocalTerminalActivator.PLUGIN_ID +
  56. ".lineseparator"; //$NON-NLS-1$
  57. private final static String[] EMPTY = {};
  58. private final static String STRING = null;
  59. private final static String TERM = "TERM"; //$NON-NLS-1$
  60. private final static String ANSI = "ansi"; //$NON-NLS-1$
  61. private final static Map TERM_ANSI = Collections.singletonMap(TERM, ANSI);
  62. // These constants were copied from IExternalToolConstants to avoid references to internal API:
  63. //
  64. private final static String XT = "org.eclipse.ui.externaltools"; //$NON-NLS-1$;
  65. private final static String ATTR_LOCATION = XT+".ATTR_LOCATION"; //$NON-NLS-1$
  66. private final static String ATTR_TOOL_ARGUMENTS = XT+".ATTR_TOOL_ARGUMENTS"; //$NON-NLS-1$
  67. private final static String ATTR_WORKING_DIRECTORY = XT+".ATTR_WORKING_DIRECTORY"; //$NON-NLS-1$
  68. private LocalTerminalLaunchUtilities() {
  69. super();
  70. }
  71. /**
  72. * Gets the image that should be used for representing the given launch configuration.
  73. *
  74. * @param configuration the {@link ILaunchConfiguration}
  75. * @return an SWT {@link Image} or <code>null</code> if no suitable image was found
  76. */
  77. public static Image getImage(ILaunchConfiguration configuration) {
  78. String identifier;
  79. try {
  80. identifier = configuration.getType().getIdentifier();
  81. }
  82. catch (CoreException couldNotDetermineConfigurationType) {
  83. identifier = null;
  84. Logger.logException(couldNotDetermineConfigurationType);
  85. }
  86. if (identifier != null) {
  87. return DebugUITools.getImage(identifier);
  88. }
  89. return null;
  90. }
  91. /**
  92. * Expands and returns the location attribute of the given launch configuration. The location is
  93. * verified to point to an existing file in the local file system.
  94. *
  95. * @param configuration the {@link ILaunchConfiguration}
  96. * @return an absolute path to a file in the local file system
  97. * @throws CoreException if unable to retrieve the associated launch configuration attribute, or
  98. * if unable to resolve any variables, or if the resolved location does not point to an existing
  99. * file in the local file system
  100. */
  101. public static IPath getLocation(ILaunchConfiguration configuration) throws CoreException {
  102. Object[] configurationName = {configuration.getName()};
  103. String location = configuration.getAttribute(ATTR_LOCATION, STRING);
  104. if (location == null) {
  105. abort(NLS.bind(LocalTerminalMessages.locationNotSpecified, configurationName), null, 0);
  106. }
  107. String expandedLocation = getStringVariableManager().performStringSubstitution(location);
  108. if (expandedLocation == null || expandedLocation.length() == 0) {
  109. abort(NLS.bind(LocalTerminalMessages.invalidLocation, configurationName), null, 0);
  110. }
  111. File file = new File(expandedLocation);
  112. if (!file.isFile()) {
  113. abort(NLS.bind(LocalTerminalMessages.invalidLocation, configurationName), null, 0);
  114. }
  115. return new Path(expandedLocation);
  116. }
  117. /**
  118. * Expands and returns the working directory attribute of the given launch configuration.
  119. * Returns <code>null</code> if a working directory is not specified. If specified, the working
  120. * directory is guaranteed to point to an existing directory in the local file system.
  121. *
  122. * @param configuration the {@link ILaunchConfiguration}
  123. * @return an absolute path to a directory in the local file system, or <code>null</code> if
  124. * no working directory was specified
  125. * @throws CoreException if unable to retrieve the associated launch configuration attribute,
  126. * or if unable to resolve any variables, or if the resolved location does not point to an
  127. * existing directory in the local file system
  128. */
  129. public static IPath getWorkingDirectory(ILaunchConfiguration configuration)
  130. throws CoreException {
  131. String location = configuration.getAttribute(ATTR_WORKING_DIRECTORY, STRING);
  132. if (location != null) {
  133. String expandedLocation;
  134. expandedLocation = getStringVariableManager().performStringSubstitution(location);
  135. if (expandedLocation.length() > 0) {
  136. File path = new File(expandedLocation);
  137. if (!path.isDirectory()) {
  138. Object[] detail = {expandedLocation, configuration.getName()};
  139. abort(NLS.bind(LocalTerminalMessages.invalidWorkingDirectory, detail), null, 0);
  140. }
  141. }
  142. return new Path(expandedLocation);
  143. }
  144. return null;
  145. }
  146. /**
  147. * Expands and returns the arguments attribute of the given launch configuration. Returns
  148. * <code>null</code> if arguments were not specified.
  149. *
  150. * @param configuration the {@link ILaunchConfiguration}
  151. * @return an array of resolved arguments, or <code>null</code> if no arguments were specified
  152. * @throws CoreException if unable to retrieve the associated launch configuration attribute,
  153. * or if unable to resolve any variables
  154. */
  155. public static String[] getArguments(ILaunchConfiguration configuration) throws CoreException {
  156. String arguments = configuration.getAttribute(ATTR_TOOL_ARGUMENTS, STRING);
  157. if (arguments != null) {
  158. String expanded = getStringVariableManager().performStringSubstitution(arguments);
  159. return parseStringIntoList(expanded);
  160. }
  161. return null;
  162. }
  163. /**
  164. * Creates an initial default launch configuration for starting a shell if no terminal/program
  165. * launch configurations are defined yet.
  166. *
  167. * @return new {@link ILaunchConfiguration}, or {@code null} if there were already some
  168. * terminal/program launch configurations defined
  169. */
  170. public static ILaunchConfiguration createDefaultLaunchConfiguration() {
  171. ILaunchConfiguration[] configs;
  172. ILaunchManager manager = LocalTerminalUtilities.LAUNCH_MANAGER;
  173. try {
  174. configs = manager.getLaunchConfigurations(LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE);
  175. if (configs == null || configs.length == 0) {
  176. // Create a default launch configuration only if there aren't any terminal launch
  177. // configurations defined at all:
  178. //
  179. ILaunchConfigurationWorkingCopy workingCopy;
  180. workingCopy = createNewLaunchConfigurationWorkingCopy();
  181. return workingCopy.doSave();
  182. }
  183. }
  184. catch (CoreException exception)
  185. {
  186. exception.printStackTrace(); // TODO: implement proper exception handling
  187. }
  188. return null;
  189. }
  190. /**
  191. * Creates an {@link ILaunchConfigurationWorkingCopy} that uses the default shell as its
  192. * executable and the user's home directory as the working directory.
  193. *
  194. * @return an unsaved {@link ILaunchConfigurationWorkingCopy}
  195. * @throws CoreException if the {@link ILaunchConfigurationWorkingCopy} could not be
  196. * instantiated
  197. * @see #getDefaultShell()
  198. */
  199. public static ILaunchConfigurationWorkingCopy createNewLaunchConfigurationWorkingCopy()
  200. throws CoreException {
  201. ILaunchConfigurationWorkingCopy workingCopy;
  202. ILaunchManager manager = LocalTerminalUtilities.LAUNCH_MANAGER;
  203. String userHome = System.getProperty("user.home", "/"); //$NON-NLS-1$//$NON-NLS-2$
  204. String defaultShell = getDefaultShell().getAbsolutePath();
  205. String name = defaultShell.substring(defaultShell.lastIndexOf(File.separator) + 1);
  206. Format terminalLaunchName = new MessageFormat(LocalTerminalMessages.newTerminalLaunchName);
  207. name = terminalLaunchName.format(new Object[] {name});
  208. name = manager.generateLaunchConfigurationName(name);
  209. workingCopy = LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE.newInstance(null, name);
  210. workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap(TERM_ANSI));
  211. workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true);
  212. workingCopy.setAttribute(ATTR_LOCATION, defaultShell);
  213. workingCopy.setAttribute(ATTR_WORKING_DIRECTORY, userHome);
  214. workingCopy.setAttribute(ATTR_LOCAL_ECHO, runningOnWindows());
  215. return workingCopy;
  216. }
  217. /**
  218. * Returns the system's default shell. First, this method will read the value of the environment
  219. * variable {@code SHELL}. If that variable is not set, it will default to {@code cmd.exe} on
  220. * Windows systems, and to {@code /bin/sh} on all other systems.
  221. *
  222. * @return a {@link File} pointing to the default shell (the underlying file is not guaranteed
  223. * to exist in the file system)
  224. */
  225. public static File getDefaultShell() {
  226. String shell = System.getenv("SHELL"); //$NON-NLS-1$
  227. if (shell == null) {
  228. if (runningOnWindows()) {
  229. shell = "C:\\Windows\\System32\\cmd.exe"; //$NON-NLS-1$
  230. }
  231. else {
  232. shell = "/bin/sh"; //$NON-NLS-1$
  233. }
  234. }
  235. return new File(shell);
  236. }
  237. //------------------------------------- PRIVATE SECTION --------------------------------------//
  238. private static boolean runningOnWindows() {
  239. return Platform.OS_WIN32.equals(Platform.getOS());
  240. }
  241. private static IStringVariableManager getStringVariableManager() {
  242. return VariablesPlugin.getDefault().getStringVariableManager();
  243. }
  244. private static String[] parseStringIntoList(String arguments) {
  245. if (arguments == null || arguments.length() == 0) {
  246. return EMPTY;
  247. }
  248. return DebugPlugin.parseArguments(arguments);
  249. }
  250. private static void abort(String text, Throwable exception, int code) throws CoreException {
  251. Status status;
  252. status = new Status(IStatus.ERROR, LocalTerminalActivator.PLUGIN_ID, code, text, exception);
  253. throw new CoreException(status);
  254. }
  255. }