3d4a29575ea0b1b9e52641572dcc9d1348d3f015
[phpeclipse.git] / net.sourceforge.phpeclipse.externaltools / src / net / sourceforge / phpdt / externaltools / launchConfigurations / ExternalToolsUtil.java
1 package net.sourceforge.phpdt.externaltools.launchConfigurations;
2
3 /**********************************************************************
4  Copyright (c) 2002 IBM Corp. and others. All rights reserved.
5  This file is made available under the terms of the Common Public License v1.0
6  which accompanies this distribution, and is available at
7  http://www.eclipse.org/legal/cpl-v10.html
8  �
9  Contributors:
10  **********************************************************************/
11
12 import java.io.File;
13 import java.text.MessageFormat;
14 import java.util.Map;
15
16 import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsModelMessages;
17 import net.sourceforge.phpdt.externaltools.internal.model.VariableContextManager;
18 import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolMigration;
19 import net.sourceforge.phpdt.externaltools.internal.registry.RefreshScopeVariable;
20 import net.sourceforge.phpdt.externaltools.internal.registry.RefreshScopeVariableRegistry;
21 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
22 import net.sourceforge.phpdt.externaltools.model.ToolUtil;
23 import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
24 import net.sourceforge.phpeclipse.externaltools.ExternalToolsPlugin;
25
26 import org.eclipse.core.resources.IResource;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.MultiStatus;
32 import org.eclipse.core.runtime.Path;
33 import org.eclipse.core.runtime.Status;
34 import org.eclipse.debug.core.DebugPlugin;
35 import org.eclipse.debug.core.ILaunchConfiguration;
36 import org.eclipse.debug.core.ILaunchConfigurationType;
37 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
38 import org.eclipse.debug.core.ILaunchManager;
39
40 /**
41  * Utilities for external tool launch configurations.
42  * <p>
43  * This class it not intended to be instantiated.
44  * </p>
45  */
46 public class ExternalToolsUtil {
47
48         private static final String LAUNCH_CONFIG_HANDLE = "LaunchConfigHandle"; //$NON-NLS-1$
49
50         /**
51          * Not to be instantiated.
52          */
53         private ExternalToolsUtil() {
54         };
55
56         /**
57          * Throws a core exception with an error status object built from the given
58          * message, lower level exception, and error code.
59          * 
60          * @param message
61          *            the status message
62          * @param exception
63          *            lower level exception associated with the error, or
64          *            <code>null</code> if none
65          * @param code
66          *            error code
67          */
68         protected static void abort(String message, Throwable exception, int code)
69                         throws CoreException {
70                 throw new CoreException(new Status(IStatus.ERROR,
71                                 IExternalToolConstants.PLUGIN_ID, code, message, exception));
72         }
73
74         /**
75          * Returns active variable context. The active variable context is used to
76          * expand variable expressions. If the workspace is currently being built,
77          * the context is associated with the project being built. Otherwise, the
78          * context is associated with the selected resource.
79          * 
80          * @return active variable context
81          */
82         public static ExpandVariableContext getVariableContext() {
83                 return VariableContextManager.getDefault().getVariableContext();
84         }
85
86         /**
87          * Expands and returns the location attribute of the given launch
88          * configuration, based on the given variable context. The location is
89          * verified to point to an existing file, in the local file system.
90          * 
91          * @param configuration
92          *            launch configuration
93          * @param context
94          *            context used to expand variables
95          * @return an absolute path to a file in the local file system
96          * @throws CoreException
97          *             if unable to retrieve the associated launch configuration
98          *             attribute, if unable to resolve any variables, or if the
99          *             resolved location does not point to an existing file in the
100          *             local file system
101          */
102         public static IPath getLocation(ILaunchConfiguration configuration,
103                         ExpandVariableContext context) throws CoreException {
104                 String location = configuration.getAttribute(
105                                 IExternalToolConstants.ATTR_LOCATION, (String) null);
106                 if (location == null) {
107                         abort(
108                                         MessageFormat
109                                                         .format(
110                                                                         ExternalToolsLaunchConfigurationMessages
111                                                                                         .getString("ExternalToolsUtil.Location_not_specified_by_{0}_1"), new String[] { configuration.getName() }), null, 0); //$NON-NLS-1$
112                 } else {
113                         MultiStatus status = new MultiStatus(
114                                         IExternalToolConstants.PLUGIN_ID,
115                                         0,
116                                         ExternalToolsModelMessages
117                                                         .getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
118                         String expandedLocation = ToolUtil.expandFileLocation(location,
119                                         context, status);
120                         if (status.isOK()) {
121                                 if (expandedLocation == null || expandedLocation.length() == 0) {
122                                         String msg = ExternalToolsModelMessages
123                                                         .format(
124                                                                         "DefaultRunnerContext.invalidLocation", new Object[] { configuration.getName() }); //$NON-NLS-1$
125                                         abort(msg, null, 0);
126                                 } else {
127                                         File file = new File(expandedLocation);
128                                         if (file.isFile()) {
129                                                 return new Path(expandedLocation);
130                                         } else {
131                                                 String msg = ExternalToolsModelMessages
132                                                                 .format(
133                                                                                 "DefaultRunnerContext.invalidLocation", new Object[] { configuration.getName() }); //$NON-NLS-1$
134                                                 abort(msg, null, 0);
135                                         }
136                                 }
137                         } else {
138                                 throw new CoreException(status);
139                         }
140                 }
141                 // execution will not reach here
142                 return null;
143         }
144
145         /**
146          * Expands and returns the working directory attribute of the given launch
147          * configuration, based on the given variable context. Returns
148          * <code>null</code> if a working directory is not specified. If
149          * specified, the working is verified to point to an existing directory in
150          * the local file system.
151          * 
152          * @param configuration
153          *            launch configuration
154          * @param context
155          *            context used to expand variables
156          * @return an absolute path to a direcoty in the local file system, or
157          *         <code>null</code> if unspecified
158          * @throws CoreException
159          *             if unable to retrieve the associated launch configuration
160          *             attribute, if unable to resolve any variables, or if the
161          *             resolved location does not point to an existing directory in
162          *             the local file system
163          */
164         public static IPath getWorkingDirectory(ILaunchConfiguration configuration,
165                         ExpandVariableContext context) throws CoreException {
166                 String location = configuration.getAttribute(
167                                 IExternalToolConstants.ATTR_WORKING_DIRECTORY, (String) null);
168                 if (location != null) {
169                         MultiStatus status = new MultiStatus(
170                                         IExternalToolConstants.PLUGIN_ID,
171                                         0,
172                                         ExternalToolsModelMessages
173                                                         .getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
174                         String expandedLocation = ToolUtil.expandDirectoryLocation(
175                                         location, context, status);
176                         if (status.isOK()) {
177                                 if (expandedLocation != null && expandedLocation.length() > 0) {
178                                         File path = new File(expandedLocation);
179                                         if (path.isDirectory()) {
180                                                 return new Path(expandedLocation);
181                                         } else {
182                                                 String msg = ExternalToolsModelMessages
183                                                                 .format(
184                                                                                 "DefaultRunnerContext.invalidDirectory", new Object[] { configuration.getName() }); //$NON-NLS-1$
185                                                 abort(msg, null, 0);
186                                         }
187                                 }
188                         } else {
189                                 throw new CoreException(status);
190                         }
191                 }
192                 return null;
193         }
194
195         /**
196          * Expands and returns the arguments attribute of the given launch
197          * configuration, based on the given variable context. Returns
198          * <code>null</code> if arguments are not specified.
199          * 
200          * @param configuration
201          *            launch configuration
202          * @param context
203          *            context used to expand variables
204          * @return an array of resolved arguments, or <code>null</code> if
205          *         unspecified
206          * @throws CoreException
207          *             if unable to retrieve the associated launch configuration
208          *             attribute, or if unable to resolve any variables
209          */
210         public static String[] getArguments(ILaunchConfiguration configuration,
211                         ExpandVariableContext context) throws CoreException {
212                 String args = configuration.getAttribute(
213                                 IExternalToolConstants.ATTR_TOOL_ARGUMENTS, (String) null);
214                 if (args != null) {
215                         MultiStatus status = new MultiStatus(
216                                         IExternalToolConstants.PLUGIN_ID,
217                                         0,
218                                         ExternalToolsModelMessages
219                                                         .getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
220                         String[] expandedArgs = ToolUtil.expandArguments(args, context,
221                                         status);
222                         if (status.isOK()) {
223                                 return expandedArgs;
224                         } else {
225                                 throw new CoreException(status);
226                         }
227                 }
228                 return null;
229         }
230
231         /**
232          * Returns the refresh scope specified by the given launch configuration or
233          * <code>null</code> if none.
234          * 
235          * @param configuration
236          * @return refresh scope
237          * @throws CoreException
238          *             if unable to access the associated attribute
239          */
240         public static String getRefreshScope(ILaunchConfiguration configuration)
241                         throws CoreException {
242                 return configuration.getAttribute(
243                                 IExternalToolConstants.ATTR_REFRESH_SCOPE, (String) null);
244         }
245
246         /**
247          * Returns whether the refresh scope specified by the given launch
248          * configuration is recursive.
249          * 
250          * @param configuration
251          * @return whether the refresh scope is recursive
252          * @throws CoreException
253          *             if unable to access the associated attribute
254          */
255         public static boolean isRefreshRecursive(ILaunchConfiguration configuration)
256                         throws CoreException {
257                 return configuration.getAttribute(
258                                 IExternalToolConstants.ATTR_REFRESH_RECURSIVE, false);
259         }
260
261         /**
262          * Refreshes the resources as specified by the given launch configuration.
263          * 
264          * @param configuration
265          *            launch configuration
266          * @param context
267          *            context used to expand variables
268          * @param monitor
269          *            progress monitor
270          * @throws CoreException
271          *             if an exception occurrs while refreshing resources
272          */
273         public static void refreshResources(ILaunchConfiguration configuration,
274                         ExpandVariableContext context, IProgressMonitor monitor)
275                         throws CoreException {
276                 String scope = getRefreshScope(configuration);
277                 if (scope == null)
278                         return;
279
280                 ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(scope,
281                                 0);
282                 if (varDef.start == -1 || varDef.end == -1 || varDef.name == null) {
283                         String msg = ExternalToolsModelMessages
284                                         .format(
285                                                         "DefaultRunnerContext.invalidRefreshVarFormat", new Object[] { configuration.getName() }); //$NON-NLS-1$
286                         abort(msg, null, 0);
287                 }
288
289                 RefreshScopeVariableRegistry registry = ExternalToolsPlugin
290                                 .getDefault().getRefreshVariableRegistry();
291                 RefreshScopeVariable variable = registry
292                                 .getRefreshVariable(varDef.name);
293                 if (variable == null) {
294                         String msg = ExternalToolsModelMessages
295                                         .format(
296                                                         "DefaultRunnerContext.noRefreshVarNamed", new Object[] { configuration.getName(), varDef.name }); //$NON-NLS-1$
297                         abort(msg, null, 0);
298                 }
299
300                 int depth = IResource.DEPTH_ZERO;
301                 if (isRefreshRecursive(configuration))
302                         depth = IResource.DEPTH_INFINITE;
303
304                 if (monitor.isCanceled())
305                         return;
306
307                 IResource[] resources = variable.getExpander().getResources(
308                                 varDef.name, varDef.argument, context);
309                 if (resources == null || resources.length == 0)
310                         return;
311
312                 monitor.beginTask(ExternalToolsModelMessages
313                                 .getString("DefaultRunnerContext.refreshResources"), //$NON-NLS-1$
314                                 resources.length);
315
316                 MultiStatus status = new MultiStatus(
317                                 IExternalToolConstants.PLUGIN_ID,
318                                 0,
319                                 ExternalToolsLaunchConfigurationMessages
320                                                 .getString("ExternalToolsUtil.Exception(s)_occurred_during_refresh._2"), null); //$NON-NLS-1$
321                 for (int i = 0; i < resources.length; i++) {
322                         if (monitor.isCanceled())
323                                 break;
324                         if (resources[i] != null && resources[i].isAccessible()) {
325                                 try {
326                                         resources[i].refreshLocal(depth, null);
327                                 } catch (CoreException e) {
328                                         status.merge(e.getStatus());
329                                 }
330                         }
331                         monitor.worked(1);
332                 }
333
334                 monitor.done();
335                 if (!status.isOK()) {
336                         throw new CoreException(status);
337                 }
338         }
339
340         /**
341          * Returns whether this tool is to be run in the background..
342          * 
343          * @param configuration
344          * @return whether this tool is to be run in the background
345          * @throws CoreException
346          *             if unable to access the associated attribute
347          */
348         public static boolean isBackground(ILaunchConfiguration configuration)
349                         throws CoreException {
350                 return configuration.getAttribute(
351                                 IExternalToolConstants.ATTR_RUN_IN_BACKGROUND, false);
352         }
353
354         /**
355          * Returns a launch configuration from the given ICommand arguments. If the
356          * given arguments are from an old-style external tool, an unsaved working
357          * copy will be created from the arguments and returned.
358          * 
359          * @param commandArgs
360          *            the builder ICommand arguments
361          * @param newName
362          *            a new name for the config if the one in the command is invalid
363          * @return a launch configuration, a launch configuration working copy, or
364          *         <code>null</code> if not possible.
365          */
366         public static ILaunchConfiguration configFromBuildCommandArgs(
367                         Map commandArgs) {
368                 String configHandle = (String) commandArgs.get(LAUNCH_CONFIG_HANDLE);
369                 if (configHandle == null) {
370                         // Probably an old-style external tool. Try to migrate.
371                         return ExternalToolMigration.configFromArgumentMap(commandArgs);
372                 }
373                 try {
374                         return DebugPlugin.getDefault().getLaunchManager()
375                                         .getLaunchConfiguration(configHandle);
376                 } catch (CoreException e) {
377                         return null;
378                 }
379         }
380
381         /**
382          * Executes an external progam and saves the LaunchConfiguration under
383          * external tools
384          * 
385          * @param command
386          *            external tools command name
387          * @param executable
388          *            executable path i.e.c:\apache\apache.exe
389          * @param arguments
390          *            arguments for this configuration
391          * @param background
392          *            run this configuration in background mode
393          */
394         public static void execute(String command, String executable,
395                         String arguments, boolean background) {
396                 execute(command, executable, null, arguments, background);
397         }
398
399         public static void execute(String command, String executable,
400                         String workingDirectory, String arguments, boolean background) {
401                 ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
402                 ILaunchConfigurationType type = manager
403                                 .getLaunchConfigurationType(IExternalToolConstants.ID_PROGRAM_LAUNCH_CONFIGURATION_TYPE);
404
405                 ILaunchConfigurationWorkingCopy wc = null;
406                 try {
407                         wc = type.newInstance(null, command);
408                 } catch (CoreException e) {
409                         // some exception handling
410                 }
411                 wc.setAttribute(IExternalToolConstants.ATTR_LOCATION, executable);
412                 if (workingDirectory != null) {
413                         wc.setAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY,
414                                         workingDirectory);
415                 }
416                 if (arguments != null) {
417                         wc.setAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS,
418                                         arguments);
419                 }
420                 wc.setAttribute(IExternalToolConstants.ATTR_RUN_IN_BACKGROUND,
421                                 background);
422
423                 // saving will add the configuration to the external tools
424                 // configurations
425                 ILaunchConfiguration config;
426                 try {
427                         config = wc.doSave();
428                         config.launch(ILaunchManager.RUN_MODE, null);
429                 } catch (CoreException e) {
430                 }
431
432         }
433 }