KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > model > AntUtil


1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ant.internal.ui.model;
12
13
14 import java.io.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.net.MalformedURLException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.text.MessageFormat JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Arrays JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.StringTokenizer JavaDoc;
24
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.util.FileUtils;
27 import org.eclipse.ant.core.AntCorePlugin;
28 import org.eclipse.ant.core.AntCorePreferences;
29 import org.eclipse.ant.core.AntRunner;
30 import org.eclipse.ant.core.TargetInfo;
31 import org.eclipse.ant.internal.core.AntClasspathEntry;
32 import org.eclipse.ant.internal.ui.launchConfigurations.AntHomeClasspathEntry;
33 import org.eclipse.ant.internal.ui.launchConfigurations.IAntLaunchConfigurationConstants;
34 import org.eclipse.ant.internal.ui.views.AntView;
35 import org.eclipse.core.resources.IFile;
36 import org.eclipse.core.resources.IWorkspaceRoot;
37 import org.eclipse.core.resources.ResourcesPlugin;
38 import org.eclipse.core.runtime.CoreException;
39 import org.eclipse.core.runtime.IPath;
40 import org.eclipse.core.runtime.IStatus;
41 import org.eclipse.core.runtime.Path;
42 import org.eclipse.core.runtime.Status;
43 import org.eclipse.core.variables.VariablesPlugin;
44 import org.eclipse.debug.core.ILaunchConfiguration;
45 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
46 import org.eclipse.debug.ui.console.FileLink;
47 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
48 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
49 import org.eclipse.jdt.launching.IRuntimeClasspathEntry2;
50 import org.eclipse.jdt.launching.JavaRuntime;
51 import org.eclipse.ui.IWorkbenchPage;
52 import org.eclipse.ui.IWorkbenchWindow;
53 import org.eclipse.ui.PlatformUI;
54
55 /**
56  * General utility class dealing with Ant build files
57  */

58 public final class AntUtil {
59     public static final String JavaDoc ATTRIBUTE_SEPARATOR = ","; //$NON-NLS-1$;
60
public static final char ANT_CLASSPATH_DELIMITER= '*';
61     public static final String JavaDoc ANT_HOME_CLASSPATH_PLACEHOLDER= "G"; //$NON-NLS-1$
62
public static final String JavaDoc ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER= "UG"; //$NON-NLS-1$
63
/**
64      * No instances allowed
65      */

66     private AntUtil() {
67         super();
68     }
69     
70     /**
71      * Returns a single-string of the strings for storage.
72      *
73      * @param strings the array of strings
74      * @return a single-string representation of the strings or
75      * <code>null</code> if the array is empty.
76      */

77     public static String JavaDoc combineStrings(String JavaDoc[] strings) {
78         if (strings.length == 0)
79             return null;
80
81         if (strings.length == 1)
82             return strings[0];
83
84         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
85         for (int i = 0; i < strings.length - 1; i++) {
86             buf.append(strings[i]);
87             buf.append(ATTRIBUTE_SEPARATOR);
88         }
89         buf.append(strings[strings.length - 1]);
90         return buf.toString();
91     }
92
93     /**
94      * Returns an array of targets to be run, or <code>null</code> if none are
95      * specified (indicating the default target should be run).
96      *
97      * @param configuration launch configuration
98      * @return array of target names, or <code>null</code>
99      * @throws CoreException if unable to access the associated attribute
100      */

101     public static String JavaDoc[] getTargetsFromConfig(ILaunchConfiguration configuration) throws CoreException {
102         String JavaDoc attribute = configuration.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_TARGETS, (String JavaDoc) null);
103         if (attribute == null) {
104             return null;
105         }
106         return AntUtil.parseRunTargets(attribute);
107     }
108     
109     /**
110      * Returns a map of properties to be defined for the build, or
111      * <code>null</code> if none are specified (indicating no additional
112      * properties specified for the build).
113      *
114      * @param configuration launch configuration
115      * @return map of properties (name --> value), or <code>null</code>
116      * @throws CoreException if unable to access the associated attribute
117      */

118     public static Map JavaDoc getProperties(ILaunchConfiguration configuration) throws CoreException {
119         Map JavaDoc map = configuration.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTIES, (Map JavaDoc) null);
120         return map;
121     }
122     
123     /**
124      * Returns a String specifying the Ant home to use for the build, or
125      * <code>null</code> if none is specified.
126      *
127      * @param configuration launch configuration
128      * @return String specifying Ant home to use, or <code>null</code>
129      * @throws CoreException if unable to access the associated attribute
130      */

131     public static String JavaDoc getAntHome(ILaunchConfiguration configuration) throws CoreException {
132         IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
133         for (int i = 0; i < entries.length; i++) {
134             IRuntimeClasspathEntry entry = entries[i];
135             if (entry.getType() == IRuntimeClasspathEntry.OTHER) {
136                 IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2)entry;
137                 if (entry2.getTypeId().equals(AntHomeClasspathEntry.TYPE_ID)) {
138                     return ((AntHomeClasspathEntry)entry2).getAntHome();
139                 }
140             }
141         }
142         return null;
143     }
144
145     /**
146      * Returns an array of property files to be used for the build, or
147      * <code>null</code> if none are specified (indicating no additional
148      * property files specified for the build).
149      *
150      * @param configuration launch configuration
151      * @return array of property file names, or <code>null</code>
152      * @throws CoreException if unable to access the associated attribute
153      */

154     public static String JavaDoc[] getPropertyFiles(ILaunchConfiguration configuration) throws CoreException {
155         String JavaDoc attribute = configuration.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_PROPERTY_FILES, (String JavaDoc) null);
156         if (attribute == null) {
157             return null;
158         }
159         String JavaDoc[] propertyFiles= AntUtil.parseString(attribute, ","); //$NON-NLS-1$
160
for (int i = 0; i < propertyFiles.length; i++) {
161             String JavaDoc propertyFile = propertyFiles[i];
162             propertyFile= expandVariableString(propertyFile, AntUIModelMessages.getString("AntUtil.6")); //$NON-NLS-1$ //$NON-NLS-2$
163
propertyFiles[i]= propertyFile;
164         }
165         return propertyFiles;
166     }
167     
168     /**
169      * Returns the list of all targets for the Ant build file specified by
170      * the provided IPath, or <code>null</code> if no targets found.
171      *
172      * @param path the location of the Ant build file to get the targets from
173      * @return a list of <code>TargetInfo</code>
174      *
175      * @throws CoreException if file does not exist, IO problems, or invalid format.
176      */

177     public static TargetInfo[] getTargets(String JavaDoc path) throws CoreException {
178         AntRunner runner = new AntRunner();
179         runner.setBuildFileLocation(path);
180         return runner.getAvailableTargets();
181     }
182     
183     /**
184      * Returns the list of all targets for the Ant build file specified by
185      * the provided IPath, arguments and ILaunchConfiguration, or <code>null</code> if no targets found.
186      *
187      * @param path the location of the Ant build file to get the targets from
188      * @param arguments command line arguments for the Ant build
189      * @param config the launch configuration for the Ant build
190      * @return a list of <code>TargetInfo</code>
191      *
192      * @throws CoreException if file does not exist, IO problems, or invalid format.
193      */

194     public static TargetInfo[] getTargets(String JavaDoc path, String JavaDoc[] arguments, ILaunchConfiguration config) throws CoreException {
195         Map JavaDoc properties=getProperties(config);
196         String JavaDoc[] propertyFiles= getPropertyFiles(config);
197         AntRunner runner = new AntRunner();
198         runner.setBuildFileLocation(path);
199         if (properties != null){
200             runner.addUserProperties(properties);
201         }
202         if (propertyFiles != null && propertyFiles.length > 0) {
203             runner.setPropertyFiles(propertyFiles);
204         }
205         if (arguments != null && arguments.length > 0) {
206             runner.setArguments(arguments);
207         }
208         runner.setCustomClasspath(getCustomClasspath(config));
209         
210         String JavaDoc antHome= getAntHome(config);
211         if (antHome != null) {
212             runner.setAntHome(antHome);
213         }
214         return runner.getAvailableTargets();
215     }
216     
217     /**
218      * Returns the list of urls that define the custom classpath for the Ant
219      * build, or <code>null</code> if the global classpath is to be used.
220      *
221      * @param config launch configuration
222      * @return a list of <code>URL</code>
223      *
224      * @throws CoreException if file does not exist, IO problems, or invalid format.
225      */

226     public static URL JavaDoc[] getCustomClasspath(ILaunchConfiguration config) throws CoreException {
227         boolean useDefault = config.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
228         if (useDefault) {
229             return null;
230         }
231         IRuntimeClasspathEntry[] unresolved = JavaRuntime.computeUnresolvedRuntimeClasspath(config);
232         // don't consider bootpath entries
233
List JavaDoc userEntries = new ArrayList JavaDoc(unresolved.length);
234         for (int i = 0; i < unresolved.length; i++) {
235             IRuntimeClasspathEntry entry = unresolved[i];
236             if (entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
237                 userEntries.add(entry);
238             }
239         }
240         IRuntimeClasspathEntry[] entries = JavaRuntime.resolveRuntimeClasspath((IRuntimeClasspathEntry[])userEntries.toArray(new IRuntimeClasspathEntry[userEntries.size()]), config);
241         URL JavaDoc[] urls = new URL JavaDoc[entries.length];
242         for (int i = 0; i < entries.length; i++) {
243             IRuntimeClasspathEntry entry = entries[i];
244             try {
245                 urls[i] = new URL JavaDoc("file:"+entry.getLocation()); //$NON-NLS-1$
246
} catch (MalformedURLException JavaDoc e) {
247                 throw new CoreException(new Status(IStatus.ERROR, AntUIPlugin.getUniqueIdentifier(), AntUIPlugin.INTERNAL_ERROR, AntUIModelMessages.getString("AntUtil.7"), e)); //$NON-NLS-1$
248
}
249         }
250         return urls;
251     }
252     
253     /**
254      * Adds the Ant home entries and additional entries to the provided lists.
255      * If no custom classpath is set, no entries are added to the lists.
256      *
257      * @param config launch configuration
258      * @param antHomeEntries list to add the Ant home entries to
259      * @param additionalEntries list to add the additional entries to
260      * @deprecated this method is no longer supported (should be deleted with
261      * old classpath tab support)
262      */

263     public static void getCustomClasspaths(ILaunchConfiguration config, List JavaDoc antHomeEntries, List JavaDoc additionalEntries) {
264         String JavaDoc classpathString= null;
265         try {
266             classpathString = config.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_CUSTOM_CLASSPATH, (String JavaDoc) null);
267         } catch (CoreException e) {
268         }
269         if (classpathString == null) {
270             return;
271         }
272         String JavaDoc antString= null;
273         String JavaDoc userString= null;
274         int delim= classpathString.indexOf(ANT_CLASSPATH_DELIMITER);
275
276         if (delim == -1) {
277             antString= classpathString;
278         } else {
279             antString= classpathString.substring(0, delim);
280             userString= classpathString.substring(delim+1);
281         }
282
283         getEntries(antHomeEntries, antString);
284         
285         if (userString != null) {
286             getEntries(additionalEntries, userString);
287         }
288     }
289     
290     private static void getEntries(List JavaDoc entries, String JavaDoc urlString) {
291         String JavaDoc[] entryStrings= AntUtil.parseString(urlString, AntUtil.ATTRIBUTE_SEPARATOR);
292         AntCorePreferences prefs= AntCorePlugin.getPlugin().getPreferences();
293         for (int i = 0; i < entryStrings.length; i++) {
294             String JavaDoc string = entryStrings[i];
295             if (string.equals(ANT_HOME_CLASSPATH_PLACEHOLDER)) {
296                 entries.addAll(Arrays.asList(prefs.getAntHomeClasspathEntries()));
297             } else if (string.equals(ANT_GLOBAL_USER_CLASSPATH_PLACEHOLDER)) {
298                 entries.addAll(Arrays.asList(prefs.getAdditionalClasspathEntries()));
299             } else {
300                 if (string.charAt(0) == '?') {
301                     string= string.substring(1);
302                 }
303                 entries.add(new AntClasspathEntry(string));
304             }
305         }
306     }
307
308     private static String JavaDoc expandVariableString(String JavaDoc variableString, String JavaDoc invalidMessage) throws CoreException {
309         String JavaDoc expandedString = VariablesPlugin.getDefault().getStringVariableManager().performStringSubstitution(variableString);
310         if (expandedString == null || expandedString.length() == 0) {
311             String JavaDoc msg = MessageFormat.format(invalidMessage, new String JavaDoc[] {variableString});
312             throw new CoreException(new Status(IStatus.ERROR, IAntUIConstants.PLUGIN_ID, 0, msg, null));
313         }
314         
315         return expandedString;
316     }
317
318     /**
319      * Returns the currently displayed Ant View if it is open.
320      *
321      * @return the Ant View open in the current workbench page or
322      * <code>null</code> if there is none.
323      */

324     public static AntView getAntView() {
325         IWorkbenchWindow window= PlatformUI.getWorkbench().getActiveWorkbenchWindow();
326         if (window != null) {
327             IWorkbenchPage page= window.getActivePage();
328             if (page != null) {
329                 return (AntView) page.findView(IAntUIConstants.ANT_VIEW_ID);
330             }
331         }
332         return null;
333     }
334     
335     /**
336      * Returns the list of target names to run
337      *
338      * @param extraAttibuteValue the external tool's extra attribute value
339      * for the run targets key.
340      * @return a list of target names
341      */

342     public static String JavaDoc[] parseRunTargets(String JavaDoc extraAttibuteValue) {
343         return parseString(extraAttibuteValue, ATTRIBUTE_SEPARATOR);
344     }
345     
346     /**
347      * Returns the list of Strings that were delimiter separated.
348      *
349      * @param delimString the String to be tokenized based on the delimiter
350      * @return a list of Strings
351      */

352     public static String JavaDoc[] parseString(String JavaDoc delimString, String JavaDoc delim) {
353         if (delimString == null) {
354             return new String JavaDoc[0];
355         }
356         
357         // Need to handle case where separator character is
358
// actually part of the target name!
359
StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(delimString, delim);
360         String JavaDoc[] results = new String JavaDoc[tokenizer.countTokens()];
361         for (int i = 0; i < results.length; i++) {
362             results[i] = tokenizer.nextToken();
363         }
364         
365         return results;
366     }
367     
368     /**
369      * Returns an IFile with the given fully qualified path (relative to the workspace root).
370      * The returned IFile may or may not exist.
371      */

372     public static IFile getFile(String JavaDoc fullPath) {
373         IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
374         return root.getFile(new Path(fullPath));
375     }
376
377     public static FileLink getTaskLink(String JavaDoc path, File JavaDoc buildFileParent) {
378         path = path.trim();
379         if (path.length() == 0) {
380             return null;
381         }
382         if (path.startsWith("file:")) { //$NON-NLS-1$
383
// remove "file:"
384
path= path.substring(5, path.length());
385         }
386         // format is file:F:L: where F is file path, and L is line number
387
int index = path.lastIndexOf(':');
388         if (index == path.length() - 1) {
389             // remove trailing ':'
390
path = path.substring(0, index);
391             index = path.lastIndexOf(':');
392         }
393         // split file and line number
394
String JavaDoc fileName = path.substring(0, index);
395         IFile file = getFileForLocation(fileName, buildFileParent);
396         if (file != null) {
397             try {
398                 String JavaDoc lineNumber = path.substring(index + 1);
399                 int line = Integer.parseInt(lineNumber);
400                 return new FileLink(file, null, -1, -1, line);
401             } catch (NumberFormatException JavaDoc e) {
402             }
403         }
404         return null;
405     }
406
407     /**
408      * Returns the workspace file associated with the given path in the
409      * local file system, or <code>null</code> if none.
410      * If the path happens to be a relative path, then the path is interpreted as
411      * relative to the specified parent file.
412      *
413      * Attempts to handle linked files; the first found linked file with the correct
414      * path is returned.
415      *
416      * @param path
417      * @param buildFileParent
418      * @return file or <code>null</code>
419      * @see org.eclipse.core.resources.IWorkspaceRoot#findFilesForLocation(IPath)
420      */

421     public static IFile getFileForLocation(String JavaDoc path, File JavaDoc buildFileParent) {
422         IPath filePath= new Path(path);
423         IFile file = null;
424         IFile[] files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(filePath);
425         if (files.length > 0) {
426             file= files[0];
427         }
428         if (file == null) {
429             //relative path
430
File JavaDoc relativeFile= null;
431             try {
432                 //this call is ok if buildFileParent is null
433
relativeFile= FileUtils.newFileUtils().resolveFile(buildFileParent, path);
434                 filePath= new Path(relativeFile.getAbsolutePath());
435                 files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(filePath);
436                 if (files.length > 0) {
437                     file= files[0];
438                 } else {
439                     return null;
440                 }
441             } catch (BuildException be) {
442                 return null;
443             }
444         }
445         
446         if (file.exists()) {
447             return file;
448         }
449         File JavaDoc ioFile= file.getLocation().toFile();
450         if (ioFile.exists()) {//needs to handle case insensitivity on WINOS
451
try {
452                 files= ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(new Path(ioFile.getCanonicalPath()));
453                 if (files.length > 0) {
454                     return files[0];
455                 }
456             } catch (IOException JavaDoc e) {
457             }
458         }
459             
460         return null;
461     }
462
463     /**
464      * Migrates the classpath in the given configuration from the old format
465      * to the new foramt. The old format is not preserved. Instead, the default
466      * classpath will be used. However, ANT_HOME settings are preserved.
467      *
468      * @param configuration a configuration to migrate
469      * @throws CoreException if unable to migrate
470      * @since 3.0
471      */

472     public static void migrateToNewClasspathFormat(ILaunchConfiguration configuration) throws CoreException {
473         String JavaDoc oldClasspath = configuration.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_CUSTOM_CLASSPATH, (String JavaDoc)null);
474         String JavaDoc oldAntHome = configuration.getAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_HOME, (String JavaDoc)null);
475         String JavaDoc provider = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, (String JavaDoc)null);
476         if (oldClasspath != null || oldAntHome != null || provider == null) {
477             ILaunchConfigurationWorkingCopy workingCopy = null;
478             if (configuration.isWorkingCopy()) {
479                 workingCopy = (ILaunchConfigurationWorkingCopy) configuration;
480             } else {
481                 workingCopy = configuration.getWorkingCopy();
482             }
483             workingCopy.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_CUSTOM_CLASSPATH, (String JavaDoc)null);
484             workingCopy.setAttribute(IAntLaunchConfigurationConstants.ATTR_ANT_HOME, (String JavaDoc)null);
485             workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, "org.eclipse.ant.ui.AntClasspathProvider"); //$NON-NLS-1$
486
workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
487             if (oldAntHome != null) {
488                 IRuntimeClasspathEntry[] entries = JavaRuntime.computeUnresolvedRuntimeClasspath(workingCopy);
489                 List JavaDoc mementos = new ArrayList JavaDoc(entries.length);
490                 for (int i = 0; i < entries.length; i++) {
491                     IRuntimeClasspathEntry entry = entries[i];
492                     if (entry.getType() == IRuntimeClasspathEntry.OTHER) {
493                         IRuntimeClasspathEntry2 entry2 = (IRuntimeClasspathEntry2) entry;
494                         if (entry2.getTypeId().equals(AntHomeClasspathEntry.TYPE_ID)) {
495                             AntHomeClasspathEntry homeEntry = new AntHomeClasspathEntry(oldAntHome);
496                             mementos.add(homeEntry.getMemento());
497                             continue;
498                         }
499                     }
500                     mementos.add(entry.getMemento());
501                 }
502                 workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
503                 workingCopy.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, mementos);
504             }
505             workingCopy.doSave();
506         }
507     }
508 }
Popular Tags