first version of external tools
[phpeclipse.git] / net.sourceforge.phpeclipse / 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 org.eclipse.core.resources.IResource;
17 import org.eclipse.core.runtime.CoreException;
18 import org.eclipse.core.runtime.IPath;
19 import org.eclipse.core.runtime.IProgressMonitor;
20 import org.eclipse.core.runtime.IStatus;
21 import org.eclipse.core.runtime.MultiStatus;
22 import org.eclipse.core.runtime.Path;
23 import org.eclipse.core.runtime.Status;
24 import org.eclipse.debug.core.DebugPlugin;
25 import org.eclipse.debug.core.ILaunchConfiguration;
26 import net.sourceforge.phpdt.externaltools.internal.model.ExternalToolsPlugin;
27 import net.sourceforge.phpdt.externaltools.internal.model.ToolMessages;
28 import net.sourceforge.phpdt.externaltools.internal.model.VariableContextManager;
29 import net.sourceforge.phpdt.externaltools.internal.registry.ExternalToolMigration;
30 import net.sourceforge.phpdt.externaltools.internal.registry.RefreshScopeVariable;
31 import net.sourceforge.phpdt.externaltools.internal.registry.RefreshScopeVariableRegistry;
32 import net.sourceforge.phpdt.externaltools.model.IExternalToolConstants;
33 import net.sourceforge.phpdt.externaltools.model.ToolUtil;
34 import net.sourceforge.phpdt.externaltools.variable.ExpandVariableContext;
35
36 /**
37  * Utilities for external tool launch configurations.
38  * <p>
39  * This class it not intended to be instantiated.
40  * </p>
41  */
42 public class ExternalToolsUtil {
43
44         private static final String LAUNCH_CONFIG_HANDLE = "LaunchConfigHandle"; //$NON-NLS-1$
45
46         /**
47          * Not to be instantiated.
48          */
49         private ExternalToolsUtil() {
50         };
51
52         /**
53          * Throws a core exception with an error status object built from
54          * the given message, lower level exception, and error code.
55          * 
56          * @param message the status message
57          * @param exception lower level exception associated with the
58          *  error, or <code>null</code> if none
59          * @param code error code
60          */
61         protected static void abort(String message, Throwable exception, int code) throws CoreException {
62                 throw new CoreException(new Status(IStatus.ERROR, IExternalToolConstants.PLUGIN_ID, code, message, exception));
63         }
64
65         /**
66          * Returns active variable context. The active variable context is used to
67          * expand variable expressions. If the workspace is currently being built,
68          * the context is associated with the project being built. Otherwise, the
69          * context is associated with the selected resource.
70          * 
71          * @return active variable context
72          */
73         public static ExpandVariableContext getVariableContext() {
74                 return VariableContextManager.getDefault().getVariableContext();
75         }
76
77         /**
78          * Expands and returns the location attribute of the given launch
79          * configuration, based on the given variable context. The location is
80          * verified to point to an existing file, in the local file system.
81          * 
82          * @param configuration launch configuration
83          * @param context context used to expand variables
84          * @return an absolute path to a file in the local file system  
85          * @throws CoreException if unable to retrieve the associated launch
86          * configuration attribute, if unable to resolve any variables, or if the
87          * resolved location does not point to an existing file in the local file
88          * system
89          */
90         public static IPath getLocation(ILaunchConfiguration configuration, ExpandVariableContext context) throws CoreException {
91                 String location = configuration.getAttribute(IExternalToolConstants.ATTR_LOCATION, (String) null);
92                 if (location == null) {
93                         abort(MessageFormat.format(ExternalToolsLaunchConfigurationMessages.getString("ExternalToolsUtil.Location_not_specified_by_{0}_1"), new String[] { configuration.getName()}), null, 0); //$NON-NLS-1$
94                 } else {
95                         MultiStatus status = new MultiStatus(IExternalToolConstants.PLUGIN_ID, 0, ToolMessages.getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
96                         String expandedLocation = ToolUtil.expandFileLocation(location, context, status);
97                         if (status.isOK()) {
98                                 if (expandedLocation == null || expandedLocation.length() == 0) {
99                                         String msg = ToolMessages.format("DefaultRunnerContext.invalidLocation", new Object[] { configuration.getName()}); //$NON-NLS-1$
100                                         abort(msg, null, 0);
101                                 } else {
102                                         File file = new File(expandedLocation);
103                                         if (file.isFile()) {
104                                                 return new Path(expandedLocation);
105                                         } else {
106                                                 String msg = ToolMessages.format("DefaultRunnerContext.invalidLocation", new Object[] { configuration.getName()}); //$NON-NLS-1$
107                                                 abort(msg, null, 0);
108                                         }
109                                 }
110                         } else {
111                                 throw new CoreException(status);
112                         }
113                 }
114                 // execution will not reach here
115                 return null;
116         }
117
118         /**
119          * Expands and returns the working directory attribute of the given launch
120          * configuration, based on the given variable context. Returns
121          * <code>null</code> if a working directory is not specified. If specified,
122          * the working is verified to point to an existing directory in the local
123          * file system.
124          * 
125          * @param configuration launch configuration
126          * @param context context used to expand variables
127          * @return an absolute path to a direcoty in the local file system, or
128          * <code>null</code> if unspecified
129          * @throws CoreException if unable to retrieve the associated launch
130          * configuration attribute, if unable to resolve any variables, or if the
131          * resolved location does not point to an existing directory in the local
132          * file system
133          */
134         public static IPath getWorkingDirectory(ILaunchConfiguration configuration, ExpandVariableContext context) throws CoreException {
135                 String location = configuration.getAttribute(IExternalToolConstants.ATTR_WORKING_DIRECTORY, (String) null);
136                 if (location != null) {
137                         MultiStatus status = new MultiStatus(IExternalToolConstants.PLUGIN_ID, 0, ToolMessages.getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
138                         String expandedLocation = ToolUtil.expandDirectoryLocation(location, context, status);
139                         if (status.isOK()) {
140                                 if (expandedLocation != null && expandedLocation.length() > 0) {
141                                         File path = new File(expandedLocation);
142                                         if (path.isDirectory()) {
143                                                 return new Path(expandedLocation);
144                                         } else {
145                                                 String msg = ToolMessages.format("DefaultRunnerContext.invalidDirectory", new Object[] { configuration.getName()}); //$NON-NLS-1$
146                                                 abort(msg, null, 0);
147                                         }
148                                 }
149                         } else {
150                                 throw new CoreException(status);
151                         }
152                 }
153                 return null;
154         }
155
156         /**
157          * Expands and returns the arguments attribute of the given launch
158          * configuration, based on the given variable context. Returns
159          * <code>null</code> if arguments are not specified.
160          * 
161          * @param configuration launch configuration
162          * @param context context used to expand variables
163          * @return an array of resolved arguments, or <code>null</code> if
164          * unspecified
165          * @throws CoreException if unable to retrieve the associated launch
166          * configuration attribute, or if unable to resolve any variables
167          */
168         public static String[] getArguments(ILaunchConfiguration configuration, ExpandVariableContext context) throws CoreException {
169                 String args = configuration.getAttribute(IExternalToolConstants.ATTR_TOOL_ARGUMENTS, (String) null);
170                 if (args != null) {
171                         MultiStatus status = new MultiStatus(IExternalToolConstants.PLUGIN_ID, 0, ToolMessages.getString("RunExternalToolAction.runProblem"), null); //$NON-NLS-1$;
172                         String[] expandedArgs = ToolUtil.expandArguments(args, context, status);
173                         if (status.isOK()) {
174                                 return expandedArgs;
175                         } else {
176                                 throw new CoreException(status);
177                         }
178                 }
179                 return null;
180         }
181
182         /**
183          * Returns the refresh scope specified by the given launch configuration or
184          * <code>null</code> if none.
185          * 
186          * @param configuration
187          * @return refresh scope
188          * @throws CoreException if unable to access the associated attribute
189          */
190         public static String getRefreshScope(ILaunchConfiguration configuration) throws CoreException {
191                 return configuration.getAttribute(IExternalToolConstants.ATTR_REFRESH_SCOPE, (String) null);
192         }
193
194         /**
195          * Returns whether the refresh scope specified by the given launch
196          * configuration is recursive.
197          * 
198          * @param configuration
199          * @return whether the refresh scope is recursive
200          * @throws CoreException if unable to access the associated attribute
201          */
202         public static boolean isRefreshRecursive(ILaunchConfiguration configuration) throws CoreException {
203                 return configuration.getAttribute(IExternalToolConstants.ATTR_REFRESH_RECURSIVE, false);
204         }
205
206         /**
207          * Refreshes the resources as specified by the given launch configuration.
208          * 
209          * @param configuration launch configuration
210          * @param context context used to expand variables
211          * @param monitor progress monitor
212          * @throws CoreException if an exception occurrs while refreshing resources
213          */
214         public static void refreshResources(ILaunchConfiguration configuration, ExpandVariableContext context, IProgressMonitor monitor) throws CoreException {
215                 String scope = getRefreshScope(configuration);
216                 if (scope == null)
217                         return;
218
219                 ToolUtil.VariableDefinition varDef = ToolUtil.extractVariableTag(scope, 0);
220                 if (varDef.start == -1 || varDef.end == -1 || varDef.name == null) {
221                         String msg = ToolMessages.format("DefaultRunnerContext.invalidRefreshVarFormat", new Object[] { configuration.getName()}); //$NON-NLS-1$
222                         abort(msg, null, 0);
223                 }
224
225                 RefreshScopeVariableRegistry registry = ExternalToolsPlugin.getDefault().getRefreshVariableRegistry();
226                 RefreshScopeVariable variable = registry.getRefreshVariable(varDef.name);
227                 if (variable == null) {
228                         String msg = ToolMessages.format("DefaultRunnerContext.noRefreshVarNamed", new Object[] { configuration.getName(), varDef.name }); //$NON-NLS-1$
229                         abort(msg, null, 0);
230                 }
231
232                 int depth = IResource.DEPTH_ZERO;
233                 if (isRefreshRecursive(configuration))
234                         depth = IResource.DEPTH_INFINITE;
235
236                 if (monitor.isCanceled())
237                         return;
238
239                 IResource[] resources = variable.getExpander().getResources(varDef.name, varDef.argument, context);
240                 if (resources == null || resources.length == 0)
241                         return;
242
243                 monitor.beginTask(ToolMessages.getString("DefaultRunnerContext.refreshResources"), //$NON-NLS-1$
244                 resources.length);
245
246                 MultiStatus status = new MultiStatus(IExternalToolConstants.PLUGIN_ID, 0, ExternalToolsLaunchConfigurationMessages.getString("ExternalToolsUtil.Exception(s)_occurred_during_refresh._2"), null); //$NON-NLS-1$
247                 for (int i = 0; i < resources.length; i++) {
248                         if (monitor.isCanceled())
249                                 break;
250                         if (resources[i] != null && resources[i].isAccessible()) {
251                                 try {
252                                         resources[i].refreshLocal(depth, null);
253                                 } catch (CoreException e) {
254                                         status.merge(e.getStatus());
255                                 }
256                         }
257                         monitor.worked(1);
258                 }
259
260                 monitor.done();
261                 if (!status.isOK()) {
262                         throw new CoreException(status);
263                 }
264         }
265
266         /**
267          * Returns whether this tool is to be run in the background..
268          * 
269          * @param configuration
270          * @return whether this tool is to be run in the background
271          * @throws CoreException if unable to access the associated attribute
272          */
273         public static boolean isBackground(ILaunchConfiguration configuration) throws CoreException {
274                 return configuration.getAttribute(IExternalToolConstants.ATTR_RUN_IN_BACKGROUND, false);
275         }
276
277         /**
278          * Returns a launch configuration from the given ICommand arguments. If the
279          * given arguments are from an old-style external tool, an unsaved working
280          * copy will be created from the arguments and returned.
281          * 
282          * @param commandArgs the builder ICommand arguments
283          * @param newName a new name for the config if the one in the command is
284          * invalid
285          * @return a launch configuration, a launch configuration working copy, or
286          * <code>null</code> if not possible.
287          */
288         public static ILaunchConfiguration configFromBuildCommandArgs(Map commandArgs) {
289                 String configHandle = (String) commandArgs.get(LAUNCH_CONFIG_HANDLE);
290                 if (configHandle == null) {
291                         // Probably an old-style external tool. Try to migrate.
292                         return ExternalToolMigration.configFromArgumentMap(commandArgs);
293                 }
294                 try {
295                         return DebugPlugin.getDefault().getLaunchManager().getLaunchConfiguration(configHandle);
296                 } catch (CoreException e) {
297                         return null;
298                 }
299         }
300 }