KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > externaltools > internal > model > BuilderUtils


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation 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  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.externaltools.internal.model;
12
13 import java.util.HashMap JavaDoc;
14 import java.util.Map JavaDoc;
15 import java.util.StringTokenizer JavaDoc;
16
17 import org.eclipse.core.resources.ICommand;
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IFolder;
20 import org.eclipse.core.resources.IProject;
21 import org.eclipse.core.resources.IResource;
22 import org.eclipse.core.resources.IncrementalProjectBuilder;
23 import org.eclipse.core.resources.ResourcesPlugin;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IConfigurationElement;
26 import org.eclipse.core.runtime.IExtensionPoint;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30 import org.eclipse.core.runtime.Path;
31 import org.eclipse.core.runtime.Platform;
32 import org.eclipse.debug.core.DebugPlugin;
33 import org.eclipse.debug.core.ILaunchConfiguration;
34 import org.eclipse.debug.core.ILaunchConfigurationType;
35 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
36 import org.eclipse.debug.core.ILaunchManager;
37 import org.eclipse.jface.dialogs.MessageDialog;
38 import org.eclipse.swt.widgets.Shell;
39 import org.eclipse.ui.externaltools.internal.registry.ExternalToolMigration;
40
41 /**
42  * Utility methods for working with external tool project builders.
43  */

44 public class BuilderUtils {
45
46     public static final String JavaDoc LAUNCH_CONFIG_HANDLE = "LaunchConfigHandle"; //$NON-NLS-1$
47

48     /**
49      * Constant used to find a builder using the 3.0-interim format
50      */

51     public static final String JavaDoc BUILDER_FOLDER_NAME= ".externalToolBuilders"; //$NON-NLS-1$
52
/**
53      * Constant used to represent the current project in the 3.0-final format.
54      */

55     public static final String JavaDoc PROJECT_TAG= "<project>"; //$NON-NLS-1$
56

57     public static final String JavaDoc VERSION_1_0= "1.0"; //$NON-NLS-1$
58
public static final String JavaDoc VERSION_2_1= "2.1"; //$NON-NLS-1$
59
// The format shipped up to and including Eclipse 3.0 RC1
60
public static final String JavaDoc VERSION_3_0_interim= "3.0.interim"; //$NON-NLS-1$
61
// The format shipped in Eclipse 3.0 final
62
public static final String JavaDoc VERSION_3_0_final= "3.0"; //$NON-NLS-1$
63

64     // Extension point constants.
65
private static final String JavaDoc TAG_CONFIGURATION_MAP= "configurationMap"; //$NON-NLS-1$
66
private static final String JavaDoc TAG_SOURCE_TYPE= "sourceType"; //$NON-NLS-1$
67
private static final String JavaDoc TAG_BUILDER_TYPE= "builderType"; //$NON-NLS-1$
68

69     private static final String JavaDoc BUILD_TYPE_SEPARATOR = ","; //$NON-NLS-1$
70
private static final int[] DEFAULT_BUILD_TYPES= new int[] {
71                                     IncrementalProjectBuilder.INCREMENTAL_BUILD,
72                                     IncrementalProjectBuilder.FULL_BUILD};
73
74     /**
75      * Returns a launch configuration from the given ICommand arguments. If the
76      * given arguments are from an old-style external tool, an unsaved working
77      * copy will be created from the arguments and returned.
78      *
79      * @param commandArgs the builder ICommand arguments
80      * @return a launch configuration, a launch configuration working copy, or
81      * <code>null</code> if not possible.
82      */

83     public static ILaunchConfiguration configFromBuildCommandArgs(IProject project, Map JavaDoc commandArgs, String JavaDoc[] version) {
84         String JavaDoc configHandle = (String JavaDoc) commandArgs.get(LAUNCH_CONFIG_HANDLE);
85         if (configHandle == null) {
86             // Probably an old-style (Eclipse 1.0 or 2.0) external tool. Try to migrate.
87
version[0]= VERSION_1_0;
88             return ExternalToolMigration.configFromArgumentMap(commandArgs);
89         }
90         ILaunchManager manager= DebugPlugin.getDefault().getLaunchManager();
91         ILaunchConfiguration configuration= null;
92         if (configHandle.startsWith(PROJECT_TAG)) {
93             version[0]= VERSION_3_0_final;
94             IPath path= new Path(configHandle);
95             IFile file= project.getFile(path.removeFirstSegments(1));
96             if (file.exists()) {
97                 configuration= manager.getLaunchConfiguration(file);
98             }
99         } else {
100             // Try treating the handle as a file name.
101
// This is the format used in 3.0 RC1.
102
IPath path= new Path(BUILDER_FOLDER_NAME).append(configHandle);
103             IFile file= project.getFile(path);
104             if (file.exists()) {
105                 version[0]= VERSION_3_0_interim;
106                 configuration= manager.getLaunchConfiguration(file);
107             } else {
108                 try {
109                     // Treat the configHandle as a memento. This is the format
110
// used in Eclipse 2.1.
111
configuration = manager.getLaunchConfiguration(configHandle);
112                 } catch (CoreException e) {
113                 }
114                 if (configuration != null) {
115                     version[0]= VERSION_2_1;
116                 }
117             }
118         }
119         return configuration;
120     }
121
122     /**
123      * Returns an <code>ICommand</code> from the given launch configuration.
124      *
125      * @param project the project the ICommand is relevant to
126      * @param config the launch configuration to create the command from
127      * @return the new command. <code>null</code> can be returned if problems occur during
128      * the translation.
129      */

130     public static ICommand commandFromLaunchConfig(IProject project, ILaunchConfiguration config) {
131         ICommand newCommand = null;
132         try {
133             newCommand = project.getDescription().newCommand();
134             newCommand = toBuildCommand(project, config, newCommand);
135             configureTriggers(config, newCommand);
136         } catch (CoreException exception) {
137             Shell shell= ExternalToolsPlugin.getActiveWorkbenchShell();
138             if (shell != null) {
139                 MessageDialog.openError(shell, ExternalToolsModelMessages.BuilderUtils_5, ExternalToolsModelMessages.BuilderUtils_6);
140             }
141             return null;
142         }
143         return newCommand;
144     }
145     
146     public static void configureTriggers(ILaunchConfiguration config, ICommand newCommand) throws CoreException {
147         newCommand.setBuilding(IncrementalProjectBuilder.FULL_BUILD, false);
148         newCommand.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, false);
149         newCommand.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
150         newCommand.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, false);
151         String JavaDoc buildKinds= config.getAttribute(IExternalToolConstants.ATTR_RUN_BUILD_KINDS, (String JavaDoc)null);
152         int[] triggers= BuilderUtils.buildTypesToArray(buildKinds);
153         for (int i = 0; i < triggers.length; i++) {
154             switch (triggers[i]) {
155                 case IncrementalProjectBuilder.FULL_BUILD:
156                     newCommand.setBuilding(IncrementalProjectBuilder.FULL_BUILD, true);
157                     break;
158                 case IncrementalProjectBuilder.INCREMENTAL_BUILD:
159                     newCommand.setBuilding(IncrementalProjectBuilder.INCREMENTAL_BUILD, true);
160                     break;
161                 case IncrementalProjectBuilder.AUTO_BUILD:
162                     newCommand.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, true);
163                     break;
164                 case IncrementalProjectBuilder.CLEAN_BUILD:
165                     newCommand.setBuilding(IncrementalProjectBuilder.CLEAN_BUILD, true);
166                     break;
167             }
168         }
169         if (!config.getAttribute(IExternalToolConstants.ATTR_TRIGGERS_CONFIGURED, false)) {
170             ILaunchConfigurationWorkingCopy copy= config.getWorkingCopy();
171             copy.setAttribute(IExternalToolConstants.ATTR_TRIGGERS_CONFIGURED, true);
172             copy.doSave();
173         }
174     }
175
176     /**
177      * Returns whether the given configuration is an "unmigrated" builder.
178      * Unmigrated builders are external tools that are stored in an old format
179      * but have not been migrated by the user. Old format builders are always
180      * translated into launch config working copies in memory, but they're not
181      * considered "migrated" until the config has been saved and the project spec
182      * updated.
183      * @param config the config to examine
184      * @return whether the given config represents an unmigrated builder
185      */

186     public static boolean isUnmigratedConfig(ILaunchConfiguration config) {
187         return config.isWorkingCopy() && ((ILaunchConfigurationWorkingCopy) config).getOriginal() == null;
188     }
189
190     /**
191      * Converts the given config to a build command which is stored in the
192      * given command.
193      *
194      * @return the configured build command
195      */

196     public static ICommand toBuildCommand(IProject project, ILaunchConfiguration config, ICommand command) throws CoreException {
197         Map JavaDoc args= null;
198         if (isUnmigratedConfig(config)) {
199             // This config represents an old external tool builder that hasn't
200
// been edited. Try to find the old ICommand and reuse the arguments.
201
// The goal here is to not change the storage format of old, unedited builders.
202
ICommand[] commands= project.getDescription().getBuildSpec();
203             for (int i = 0; i < commands.length; i++) {
204                 ICommand projectCommand = commands[i];
205                 String JavaDoc name= ExternalToolMigration.getNameFromCommandArgs(projectCommand.getArguments());
206                 if (name != null && name.equals(config.getName())) {
207                     args= projectCommand.getArguments();
208                     break;
209                 }
210             }
211         } else {
212             if (config instanceof ILaunchConfigurationWorkingCopy) {
213                 ILaunchConfigurationWorkingCopy workingCopy= (ILaunchConfigurationWorkingCopy) config;
214                 if (workingCopy.getOriginal() != null) {
215                     config= workingCopy.getOriginal();
216                 }
217             }
218             args= new HashMap JavaDoc();
219             // Launch configuration builders are stored with a project-relative path
220
StringBuffer JavaDoc buffer= new StringBuffer JavaDoc(PROJECT_TAG);
221             // Append the project-relative path (workspace path minus first segment)
222
buffer.append('/').append(config.getFile().getFullPath().removeFirstSegments(1));
223             args.put(LAUNCH_CONFIG_HANDLE, buffer.toString());
224         }
225         command.setBuilderName(ExternalToolBuilder.ID);
226         command.setArguments(args);
227         return command;
228     }
229     
230     /**
231      * Returns the type of launch configuration that should be created when
232      * duplicating the given configuration as a project builder. Queries to see
233      * if an extension has been specified to explicitly declare the mapping.
234      */

235     public static ILaunchConfigurationType getConfigurationDuplicationType(ILaunchConfiguration config) throws CoreException {
236         IExtensionPoint ep= Platform.getExtensionRegistry().getExtensionPoint(IExternalToolConstants.PLUGIN_ID, IExternalToolConstants.EXTENSION_POINT_CONFIGURATION_DUPLICATION_MAPS);
237         IConfigurationElement[] elements = ep.getConfigurationElements();
238         String JavaDoc sourceType= config.getType().getIdentifier();
239         String JavaDoc builderType= null;
240         for (int i= 0; i < elements.length; i++) {
241             IConfigurationElement element= elements[i];
242             if (element.getName().equals(TAG_CONFIGURATION_MAP) && sourceType.equals(element.getAttribute(TAG_SOURCE_TYPE))) {
243                 builderType= element.getAttribute(TAG_BUILDER_TYPE);
244                 break;
245             }
246         }
247         if (builderType != null) {
248             ILaunchConfigurationType type= DebugPlugin.getDefault().getLaunchManager().getLaunchConfigurationType(builderType);
249             if (type != null) {
250                 return type;
251             }
252         }
253         return config.getType();
254     }
255
256     /**
257      * Returns the folder where project builders should be stored or
258      * <code>null</code> if the folder could not be created
259      */

260     public static IFolder getBuilderFolder(IProject project, boolean create) {
261         IFolder folder = project.getFolder(BUILDER_FOLDER_NAME);
262         if (!folder.exists() && create) {
263             try {
264                 folder.create(true, true, new NullProgressMonitor());
265             } catch (CoreException e) {
266                 return null;
267             }
268         }
269         return folder;
270     }
271
272     /**
273      * Returns a duplicate of the given configuration. The new configuration
274      * will be of the same type as the given configuration or of the duplication
275      * type registered for the given configuration via the extension point
276      * IExternalToolConstants.EXTENSION_POINT_CONFIGURATION_DUPLICATION_MAPS.
277      */

278     public static ILaunchConfiguration duplicateConfiguration(IProject project, ILaunchConfiguration config) throws CoreException {
279         Map JavaDoc attributes= config.getAttributes();
280         String JavaDoc newName= new StringBuffer JavaDoc(config.getName()).append(ExternalToolsModelMessages.BuilderUtils_7).toString();
281         newName= DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom(newName);
282         ILaunchConfigurationType newType= getConfigurationDuplicationType(config);
283         ILaunchConfigurationWorkingCopy newWorkingCopy= newType.newInstance(getBuilderFolder(project, true), newName);
284         newWorkingCopy.setAttributes(attributes);
285         return newWorkingCopy.doSave();
286     }
287
288     /**
289      * Migrates the launch configuration working copy, which is based on an old-
290      * style external tool builder, to a new, saved launch configuration. The
291      * returned launch configuration will contain the same attributes as the
292      * given working copy with the exception of the configuration name, which
293      * may be changed during the migration. The name of the configuration will
294      * only be changed if the current name is not a valid name for a saved
295      * config.
296      *
297      * @param workingCopy the launch configuration containing attributes from an
298      * old-style project builder.
299      * @return ILaunchConfiguration a new, saved launch configuration whose
300      * attributes match those of the given working copy as well as possible
301      * @throws CoreException if an exception occurs while attempting to save the
302      * new launch configuration
303      */

304     public static ILaunchConfiguration migrateBuilderConfiguration(IProject project, ILaunchConfigurationWorkingCopy workingCopy) throws CoreException {
305         workingCopy.setContainer(getBuilderFolder(project, true));
306         // Before saving, make sure the name is valid
307
String JavaDoc name= workingCopy.getName();
308         name= name.replace('/', '.');
309         if (name.charAt(0) == ('.')) {
310             name = name.substring(1);
311         }
312         IStatus status = ResourcesPlugin.getWorkspace().validateName(name, IResource.FILE);
313         if (!status.isOK()) {
314             name = "ExternalTool"; //$NON-NLS-1$
315
}
316         name = DebugPlugin.getDefault().getLaunchManager().generateUniqueLaunchConfigurationNameFrom(name);
317         workingCopy.rename(name);
318         return workingCopy.doSave();
319     }
320
321     /**
322      * Converts the build types string into an array of
323      * build kinds.
324      *
325      * @param buildTypes the string of built types to convert
326      * @return the array of build kinds.
327      */

328     public static int[] buildTypesToArray(String JavaDoc buildTypes) {
329         if (buildTypes == null || buildTypes.length() == 0) {
330             return DEFAULT_BUILD_TYPES;
331         }
332         
333         int count = 0;
334         boolean incremental = false;
335         boolean full = false;
336         boolean auto = false;
337         boolean clean= false;
338     
339         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(buildTypes, BUILD_TYPE_SEPARATOR);
340         while (tokenizer.hasMoreTokens()) {
341             String JavaDoc token = tokenizer.nextToken();
342             if (IExternalToolConstants.BUILD_TYPE_INCREMENTAL.equals(token)) {
343                 if (!incremental) {
344                     incremental = true;
345                     count++;
346                 }
347             } else if (IExternalToolConstants.BUILD_TYPE_FULL.equals(token)) {
348                 if (!full) {
349                     full = true;
350                     count++;
351                 }
352             } else if (IExternalToolConstants.BUILD_TYPE_AUTO.equals(token)) {
353                 if (!auto) {
354                     auto = true;
355                     count++;
356                 }
357             } else if (IExternalToolConstants.BUILD_TYPE_CLEAN.equals(token)) {
358                 if (!clean) {
359                     clean = true;
360                     count++;
361                 }
362             }
363         }
364     
365         int[] results = new int[count];
366         count = 0;
367         if (incremental) {
368             results[count] = IncrementalProjectBuilder.INCREMENTAL_BUILD;
369             count++;
370         }
371         if (full) {
372             results[count] = IncrementalProjectBuilder.FULL_BUILD;
373             count++;
374         }
375         if (auto) {
376             results[count] = IncrementalProjectBuilder.AUTO_BUILD;
377             count++;
378         }
379         if (clean) {
380             results[count] = IncrementalProjectBuilder.CLEAN_BUILD;
381             count++;
382         }
383     
384         return results;
385     }
386 }
387
Popular Tags