KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > build > FetchScriptGenerator


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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 - Initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.pde.internal.build;
12
13 import java.io.*;
14 import java.util.*;
15 import org.eclipse.ant.core.AntRunner;
16 import org.eclipse.core.runtime.*;
17 import org.eclipse.osgi.util.NLS;
18 import org.eclipse.pde.build.Constants;
19 import org.eclipse.pde.build.IFetchFactory;
20 import org.eclipse.pde.internal.build.ant.AntScript;
21 import org.eclipse.pde.internal.build.fetch.CVSFetchTaskFactory;
22 import org.eclipse.update.core.*;
23 import org.eclipse.update.internal.core.FeatureExecutableFactory;
24 import org.osgi.framework.Version;
25
26 /**
27  * Generates Ant scripts with a repository specific factory
28  * to retrieve plug-ins and features from a repository.
29  */

30 public class FetchScriptGenerator extends AbstractScriptGenerator {
31     private static final String JavaDoc FETCH_TASK_FACTORY = "internal.factory"; //$NON-NLS-1$
32
private static final String JavaDoc MATCHED_VERSION = "internal.matchedVersion"; //$NON-NLS-1$
33

34     // flag saying if we want to recursively generate the scripts
35
protected boolean recursiveGeneration = true;
36
37     // Points to the map files containing references to repository
38
protected Properties directoryFile;
39     protected String JavaDoc directoryLocation;
40     protected SortedMap directory;
41
42     // The location of the CVS password file.
43
protected String JavaDoc cvsPassFileLocation;
44
45     protected boolean fetchChildren = true;
46
47     protected Properties fetchTags = null;
48
49     // The element (an entry of the map file) for which we create the script
50
protected String JavaDoc element;
51     protected Version elementVersion;
52
53     // The feature object representing the element
54
protected IFeature feature;
55     //The map infos (of the element) processed
56
protected Map mapInfos;
57     // The content of the build.properties file associated with the feature
58
protected Properties featureProperties;
59     // Variables to control is a mkdir to a specific folder was already.
60
protected List mkdirLocations = new ArrayList(5);
61     // A property table containing the association between the plugins and the version from the map
62
protected Properties repositoryPluginTags = new Properties();
63     protected Properties repositoryFeatureTags = new Properties();
64
65     //The registry of the task factories
66
private FetchTaskFactoriesRegistry fetchTaskFactories;
67     //Set of all the used factories while generating the fetch script for the top level element
68
private Set encounteredTypeOfRepo = new HashSet();
69
70     public static final String JavaDoc FEATURE_ONLY = "featureOnly"; //$NON-NLS-1$
71
public static final String JavaDoc FEATURE_AND_PLUGINS = "featureAndPlugins"; //$NON-NLS-1$
72
public static final String JavaDoc FEATURES_RECURSIVELY = "featuresRecursively"; //$NON-NLS-1$
73
public static final String JavaDoc FETCH_FILE_PREFIX = "fetch_"; //$NON-NLS-1$
74

75     private String JavaDoc scriptName;
76
77     public FetchScriptGenerator() {
78         super();
79     }
80
81     public FetchScriptGenerator(String JavaDoc element) {
82         setElement(element);
83     }
84
85     public void setElement(String JavaDoc element) {
86         Object JavaDoc[] split = splitElement(element);
87         this.element = (String JavaDoc) split[0];
88         this.elementVersion = (Version) split[1];
89     }
90
91     private Object JavaDoc[] splitElement(String JavaDoc elt) {
92         int comma = elt.indexOf(',');
93         if (comma == -1) {
94             return new Object JavaDoc[] {elt, Version.emptyVersion};
95         }
96         return new Object JavaDoc[] {elt.substring(0, comma), new Version(elt.substring(comma + 1))};
97     }
98
99     private void initializeFactories() {
100         fetchTaskFactories = new FetchTaskFactoriesRegistry();
101     }
102
103     /**
104      * @see AbstractScriptGenerator#generate()
105      */

106     public void generate() throws CoreException {
107         initializeFactories();
108         mapInfos = processMapFileEntry(element, elementVersion);
109         if (mapInfos == null) {
110             IStatus warning = new Status(IStatus.WARNING, PI_PDEBUILD, WARNING_ELEMENT_NOT_FETCHED, NLS.bind(Messages.error_fetchingFailed, element), null);
111             BundleHelper.getDefault().getLog().log(warning);
112             return;
113         }
114
115         scriptName = FETCH_FILE_PREFIX + mapInfos.get(IFetchFactory.KEY_ELEMENT_NAME) + ".xml"; //$NON-NLS-1$
116
openScript(workingDirectory, scriptName);
117         try {
118             generateFetchScript();
119         } finally {
120             closeScript();
121         }
122
123         if (recursiveGeneration && mapInfos.get(IFetchFactory.KEY_ELEMENT_TYPE).equals(IFetchFactory.ELEMENT_TYPE_FEATURE))
124             generateFetchFilesForIncludedFeatures();
125
126         saveRepositoryTags();
127     }
128
129     private void saveRepositoryTags(Properties properties, String JavaDoc fileName) throws CoreException {
130         try {
131             InputStream input = new BufferedInputStream(new FileInputStream(workingDirectory + '/' + fileName));
132             try {
133                 properties.load(input);
134             } finally {
135                 input.close();
136             }
137         } catch (IOException e) {
138             //ignore the exception, the same may not exist
139
}
140
141         try {
142             OutputStream os = new BufferedOutputStream(new FileOutputStream(workingDirectory + '/' + fileName));
143             try {
144                 properties.store(os, null);
145             } finally {
146                 os.close();
147             }
148         } catch (IOException e) {
149             String JavaDoc message = NLS.bind(Messages.exception_writingFile, workingDirectory + '/' + fileName);
150             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, null));
151         }
152     }
153
154     private void saveRepositoryTags() throws CoreException {
155         saveRepositoryTags(repositoryPluginTags, DEFAULT_PLUGIN_REPOTAG_FILENAME_DESCRIPTOR);
156         saveRepositoryTags(repositoryFeatureTags, DEFAULT_FEATURE_REPOTAG_FILENAME_DESCRIPTOR);
157     }
158
159     /**
160      * Method generateFetchFilesForRequiredFeatures.
161      */

162     private void generateFetchFilesForIncludedFeatures() throws CoreException {
163         IIncludedFeatureReference[] referencedFeatures = ((Feature) feature).getFeatureIncluded();
164         for (int i = 0; i < referencedFeatures.length; i++) {
165             String JavaDoc featureId = referencedFeatures[i].getVersionedIdentifier().getIdentifier();
166             if (featureProperties.containsKey(GENERATION_SOURCE_FEATURE_PREFIX + featureId))
167                 continue;
168
169             FetchScriptGenerator generator = new FetchScriptGenerator("feature@" + featureId + ',' + referencedFeatures[i].getVersionedIdentifier().getVersion().toString()); //$NON-NLS-1$
170
generator.setDirectoryLocation(directoryLocation);
171             generator.setFetchChildren(fetchChildren);
172             generator.setCvsPassFileLocation(cvsPassFileLocation);
173             generator.setRecursiveGeneration(recursiveGeneration);
174             generator.setFetchTag(fetchTags);
175             generator.setDirectory(directory);
176             generator.setDirectoryFile(directoryFile);
177             generator.setBuildSiteFactory(siteFactory);
178             generator.repositoryPluginTags = repositoryPluginTags;
179             generator.generate();
180         }
181     }
182
183     /**
184      * Main call for generating the script.
185      *
186      * @throws CoreException
187      */

188     protected void generateFetchScript() throws CoreException {
189         generatePrologue();
190         generateFetchTarget();
191         generateFetchElementTarget();
192         if (mapInfos.get(IFetchFactory.KEY_ELEMENT_TYPE).equals(IFetchFactory.ELEMENT_TYPE_FEATURE)) {
193             generateFetchPluginsTarget();
194             generateFetchRecusivelyTarget();
195         }
196         generateAdditionalTargets();
197         generateEpilogue();
198     }
199
200     protected void generateFetchTarget() {
201         //CONDITION Here we could check the values contained in the header of the file.
202
// However it will require to have either generic value or to be sure that the value can be omitted
203
// This would be necessary for the top level feature
204
script.println();
205         script.printTargetDeclaration(TARGET_FETCH, null, null, null, null);
206         //don't do a fetch element for the generated container feature
207
if (!mapInfos.get(IFetchFactory.KEY_ELEMENT_NAME).equals(IPDEBuildConstants.CONTAINER_FEATURE))
208             script.printAntCallTask(TARGET_FETCH_ELEMENT, true, null);
209         if (mapInfos.get(IFetchFactory.KEY_ELEMENT_TYPE).equals(IFetchFactory.ELEMENT_TYPE_FEATURE)) {
210             script.printAntCallTask(TARGET_FETCH_PLUGINS, true, null);
211             script.printAntCallTask(TARGET_FETCH_RECURSIVELY, true, null);
212         }
213         script.printTargetEnd();
214     }
215
216     protected void generateFetchElementTarget() {
217         //don't try to fetch a generated container feature
218
if (mapInfos.get(IFetchFactory.KEY_ELEMENT_NAME).equals(IPDEBuildConstants.CONTAINER_FEATURE))
219             return;
220         script.printTargetDeclaration(TARGET_FETCH_ELEMENT, null, FEATURE_ONLY, null, null);
221         try {
222             generateFetchEntry(element, elementVersion, false);
223         } catch (CoreException e) {
224             IStatus status = new Status(IStatus.ERROR, PI_PDEBUILD, WARNING_ELEMENT_NOT_FETCHED, NLS.bind(Messages.error_fetchingFailed, element), null);
225             BundleHelper.getDefault().getLog().log(status);
226         }
227         script.printTargetEnd();
228     }
229
230     protected void generateFetchPluginsTarget() throws CoreException {
231         script.printTargetDeclaration(TARGET_FETCH_PLUGINS, null, FEATURE_AND_PLUGINS, null, null);
232         retrieveFeature((String JavaDoc) mapInfos.get(IFetchFactory.KEY_ELEMENT_NAME), (String JavaDoc) mapInfos.get(IFetchFactory.KEY_ELEMENT_TYPE), mapInfos);
233         generateChildrenFetchScript();
234         script.printTargetEnd();
235     }
236
237     /**
238      * Decompose the elements constituting a Map file entry. The values are returned
239      * in a Map. <code>null</code> is returned if the entry does not exist.
240      * @param entry
241      * @return Map
242      * @throws CoreException
243      */

244     private Map processMapFileEntry(String JavaDoc entry, Version version) throws CoreException {
245         Map entryInfos = new HashMap(5);
246
247         // extract type and element from entry
248
int index = entry.indexOf('@');
249         String JavaDoc type = entry.substring(0, index);
250         String JavaDoc currentElement = entry.substring(index + 1);
251
252         // read and validate the repository info for the entry
253
Object JavaDoc[] match = getRepositoryInfo(entry, version);
254         String JavaDoc repositoryInfo = match == null ? null : (String JavaDoc) match[0];
255         if (repositoryInfo == null) {
256             if (IPDEBuildConstants.CONTAINER_FEATURE.equals(currentElement)) {
257                 entryInfos.put(IFetchFactory.KEY_ELEMENT_TYPE, type);
258                 entryInfos.put(IFetchFactory.KEY_ELEMENT_NAME, currentElement);
259                 return entryInfos;
260             }
261             String JavaDoc message = NLS.bind(Messages.error_missingDirectoryEntry, Version.emptyVersion.equals(version) ? entry : entry + ',' + version.toString());
262             BundleHelper.getDefault().getLog().log(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ENTRY_MISSING, message, null));
263             return null;
264         }
265
266         // Get the repo identifier
267
int idx = repositoryInfo.indexOf(',');
268         if (idx == -1) {
269             String JavaDoc message = NLS.bind(Messages.error_incorrectDirectoryEntry, currentElement);
270             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ENTRY_MISSING, message, null));
271         }
272         String JavaDoc repoIdentifier = repositoryInfo.substring(0, idx).trim();
273
274         // Get the repo factory corresponding
275
IFetchFactory fetchTaskFactory = null;
276         String JavaDoc repoSpecificSegment = null;
277         // if the type can not be found it is probably because it is an old style map file
278
if (!fetchTaskFactories.getFactoryIds().contains(repoIdentifier)) {
279             repoIdentifier = CVSFetchTaskFactory.ID;
280             repoSpecificSegment = repositoryInfo;
281         } else {
282             repoSpecificSegment = repositoryInfo.substring(idx + 1, repositoryInfo.length()); //TODO Need to see if we can go out idx + 1
283
}
284
285         fetchTaskFactory = fetchTaskFactories.getFactory(repoIdentifier);
286         if (fetchTaskFactory == null) {
287             String JavaDoc message = NLS.bind(Messages.error_noCorrespondingFactory, currentElement);
288             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ENTRY_MISSING, message, null));
289         }
290
291         encounteredTypeOfRepo.add(fetchTaskFactory);
292         // add general infos (will override builder specific infos)
293
entryInfos.put(IFetchFactory.KEY_ELEMENT_TYPE, type);
294         entryInfos.put(IFetchFactory.KEY_ELEMENT_NAME, currentElement);
295
296         // add infos from registered builder
297
fetchTaskFactory.parseMapFileEntry(repoSpecificSegment, fetchTags, entryInfos);
298
299         // store builder
300
entryInfos.put(FETCH_TASK_FACTORY, fetchTaskFactory);
301         
302         // keep track of the version of the element as found in the map file
303
entryInfos.put(MATCHED_VERSION, match[1]);
304         return entryInfos;
305     }
306
307     protected void generateFetchRecusivelyTarget() throws CoreException {
308         script.printTargetDeclaration(TARGET_FETCH_RECURSIVELY, null, FEATURES_RECURSIVELY, null, null);
309
310         IIncludedFeatureReference[] compiledFeatures = ((Feature) feature).getFeatureIncluded();
311         for (int i = 0; i < compiledFeatures.length; i++) {
312             String JavaDoc featureId = compiledFeatures[i].getVersionedIdentifier().getIdentifier();
313             if (featureProperties.containsKey(GENERATION_SOURCE_FEATURE_PREFIX + featureId)) {
314                 String JavaDoc[] extraElementsToFetch = Utils.getArrayFromString(featureProperties.getProperty(GENERATION_SOURCE_FEATURE_PREFIX + featureId), ","); //$NON-NLS-1$
315
for (int j = 1; j < extraElementsToFetch.length; j++) {
316                     Object JavaDoc[] infos = Utils.parseExtraBundlesString(extraElementsToFetch[j], false);
317                     generateFetchEntry((String JavaDoc) infos[0], (Version) infos[1], false);
318                 }
319                 continue;
320             }
321
322             //Included features can be available in the baseLocation.
323
if (getRepositoryInfo(IFetchFactory.ELEMENT_TYPE_FEATURE + '@' + featureId, new Version(compiledFeatures[i].getVersionedIdentifier().getVersion().toString())) != null)
324                 script.printAntTask(Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + '/' + FETCH_FILE_PREFIX + featureId + ".xml", null, TARGET_FETCH, null, null, null); //$NON-NLS-1$
325
else if (getSite(false).findFeature(featureId, null, false) == null) {
326                 String JavaDoc message = NLS.bind(Messages.error_cannotFetchNorFindFeature, featureId);
327                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, null));
328             }
329         }
330         script.printTargetEnd();
331     }
332
333     protected boolean generateFetchEntry(String JavaDoc entry, Version version, boolean manifestFileOnly) throws CoreException {
334         Map mapFileEntry = mapInfos;
335         if (!entry.equals(element)) {
336             mapFileEntry = processMapFileEntry(entry, version);
337             if (mapFileEntry == null)
338                 return false;
339         }
340
341         IFetchFactory factory = (IFetchFactory) mapFileEntry.get(FETCH_TASK_FACTORY);
342         String JavaDoc elementToFetch = (String JavaDoc) mapFileEntry.get(IFetchFactory.KEY_ELEMENT_NAME);
343         String JavaDoc type = (String JavaDoc) mapFileEntry.get(IFetchFactory.KEY_ELEMENT_TYPE);
344         if (!manifestFileOnly)
345             factory.generateRetrieveElementCall(mapFileEntry, computeFinalLocation(type, elementToFetch, (Version) mapFileEntry.get(MATCHED_VERSION)), script);
346         else {
347             String JavaDoc[] files;
348             if (type.equals(IFetchFactory.ELEMENT_TYPE_FEATURE)) {
349                 files = new String JavaDoc[] {Constants.FEATURE_FILENAME_DESCRIPTOR};
350             } else if (type.equals(IFetchFactory.ELEMENT_TYPE_PLUGIN)) {
351                 files = new String JavaDoc[] {Constants.PLUGIN_FILENAME_DESCRIPTOR, Constants.BUNDLE_FILENAME_DESCRIPTOR};
352             } else if (type.equals(IFetchFactory.ELEMENT_TYPE_FRAGMENT)) {
353                 files = new String JavaDoc[] {Constants.FRAGMENT_FILENAME_DESCRIPTOR, Constants.BUNDLE_FILENAME_DESCRIPTOR};
354             } else if (type.equals(IFetchFactory.ELEMENT_TYPE_BUNDLE)) {
355                 files = new String JavaDoc[] {Constants.BUNDLE_FILENAME_DESCRIPTOR};
356             } else {
357                 files = new String JavaDoc[0];
358             }
359             factory.generateRetrieveFilesCall(mapFileEntry, computeFinalLocation(type, elementToFetch, (Version) mapFileEntry.get(MATCHED_VERSION)), files, script);
360         }
361
362         //Keep track of the element that are being fetched. To simplify the lookup in the qualifier replacer, the versioned that was initially looked up is used as key in the file
363
Properties tags = null;
364         if (type.equals(IFetchFactory.ELEMENT_TYPE_FEATURE))
365             tags = repositoryFeatureTags;
366         else
367             tags = repositoryPluginTags;
368         if (mapFileEntry.get(IFetchFactory.KEY_ELEMENT_TAG) != null)
369             tags.put(elementToFetch + ',' + new Version(version.getMajor(), version.getMinor(), version.getMicro()), mapFileEntry.get(IFetchFactory.KEY_ELEMENT_TAG));
370
371         return true;
372     }
373
374     /**
375      * Helper method to control for what locations a mkdir Ant task was already
376      * generated so we can reduce replication.
377      *
378      * @param location
379      */

380     protected void generateMkdirs(String JavaDoc location) {
381         if (mkdirLocations.contains(location))
382             return;
383         mkdirLocations.add(location);
384         script.printMkdirTask(location);
385     }
386
387     /**
388      *
389      * @throws CoreException
390      */

391     protected void generateChildrenFetchScript() throws CoreException {
392         IPluginEntry[] allChildren = feature.getRawPluginEntries();
393         IPluginEntry[] compiledChildren = feature.getPluginEntries();
394
395         for (int i = 0; i < allChildren.length; i++) {
396             String JavaDoc elementId = allChildren[i].getVersionedIdentifier().getIdentifier();
397             Version versionId = new Version(allChildren[i].getVersionedIdentifier().getVersion().toString());
398             // We are not fetching the elements that are said to be generated, but we are fetching some elements that can be associated
399
if (featureProperties.containsKey(GENERATION_SOURCE_PLUGIN_PREFIX + elementId)) {
400                 String JavaDoc[] extraElementsToFetch = Utils.getArrayFromString(featureProperties.getProperty(GENERATION_SOURCE_PLUGIN_PREFIX + elementId), ","); //$NON-NLS-1$
401
for (int j = 1; j < extraElementsToFetch.length; j++) {
402                     Object JavaDoc[] infos = Utils.parseExtraBundlesString(extraElementsToFetch[j], false);
403                     generateFetchEntry((String JavaDoc) infos[0], (Version) infos[1], false);
404                 }
405                 continue;
406             }
407
408             boolean generated = true;
409             if (allChildren[i].isFragment())
410                 generated = generateFetchEntry(IFetchFactory.ELEMENT_TYPE_FRAGMENT + '@' + elementId, versionId, !Utils.isIn(compiledChildren, allChildren[i]));
411             else
412                 generated = generateFetchEntry(IFetchFactory.ELEMENT_TYPE_PLUGIN + '@' + elementId, versionId, !Utils.isIn(compiledChildren, allChildren[i]));
413             if (generated == false)
414                 generateFetchEntry(IFetchFactory.ELEMENT_TYPE_BUNDLE + '@' + elementId, versionId, !Utils.isIn(compiledChildren, allChildren[i]));
415         }
416     }
417
418     /**
419      * Return the feature object for the feature with the given info. Generate an Ant script
420      * which will retrieve the "feature.xml" file from CVS, and then call the feature object
421      * constructor from Update.
422      *
423      * @param elementName the feature to retrieve
424      * @param elementType the element type
425      * @param elementInfos the element information
426      * @throws CoreException
427      */

428     protected void retrieveFeature(String JavaDoc elementName, String JavaDoc elementType, Map elementInfos) throws CoreException {
429         // Generate a temporary Ant script which retrieves the feature.xml for this
430
// feature from CVS
431
File root = new File(workingDirectory);
432
433         //generated container feature should already exist on disk
434
if (elementName.equals(IPDEBuildConstants.CONTAINER_FEATURE)) {
435             FeatureExecutableFactory factory = new FeatureExecutableFactory();
436             File featuresFolder = new File(root, DEFAULT_FEATURE_LOCATION);
437             File featureLocation = new File(featuresFolder, elementName);
438             try {
439                 feature = factory.createFeature(featureLocation.toURL(), null, null);
440                 featureProperties = new Properties();
441                 InputStream featureStream = new BufferedInputStream(new FileInputStream(new File(featureLocation, PROPERTIES_FILE)));
442                 featureProperties.load(featureStream);
443                 featureStream.close();
444                 return;
445             } catch (Exception JavaDoc e) {
446                 String JavaDoc message = NLS.bind(Messages.exception_missingFeature, elementName);
447                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, e));
448             }
449         }
450
451         File target = new File(root, DEFAULT_RETRIEVE_FILENAME_DESCRIPTOR);
452         IPath destination = new Path(root.getAbsolutePath()).append("tempFeature/"); //$NON-NLS-1$
453
try {
454             AntScript retrieve = new AntScript(new BufferedOutputStream(new FileOutputStream(target)));
455             try {
456                 retrieve.printProjectDeclaration("RetrieveFeature", "main", "."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
457
retrieve.printTargetDeclaration(TARGET_MAIN, null, null, null, null);
458
459                 String JavaDoc[] files = new String JavaDoc[] {Constants.FEATURE_FILENAME_DESCRIPTOR, PROPERTIES_FILE};
460                 IFetchFactory factory = (IFetchFactory) elementInfos.get(FETCH_TASK_FACTORY);
461                 factory.generateRetrieveFilesCall(elementInfos, destination, files, retrieve);
462
463                 retrieve.printTargetEnd();
464                 retrieve.printProjectEnd();
465             } finally {
466                 retrieve.close();
467             }
468         } catch (IOException e) {
469             String JavaDoc message = NLS.bind(Messages.exception_writeScript, target);
470             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, e));
471         }
472
473         // Run the Ant script to go to and retrieve the feature.xml. Call the Update
474
// code to construct the feature object to return.
475
try {
476             AntRunner runner = new AntRunner();
477             runner.setBuildFileLocation(target.getAbsolutePath());
478             Map retrieveProp = new HashMap();
479             retrieveProp.put("fetch.failonerror", "true"); //$NON-NLS-1$//$NON-NLS-2$
480
runner.addUserProperties(retrieveProp);
481             //This has to be hardcoded here because of the way AntRunner stipulates that
482
//loggers are passed in. Otherwise this would be a Foo.class.getName()
483
runner.addBuildLogger("org.eclipse.pde.internal.build.tasks.SimpleBuildLogger"); //$NON-NLS-1$
484

485             runner.run();
486         } catch (Exception JavaDoc e) {
487             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, NLS.bind(Messages.error_retrieveFailed, elementName), e));
488         }
489         
490         try {
491             FeatureExecutableFactory factory = new FeatureExecutableFactory();
492             File featureFolder = new File(destination.toString());
493             feature = factory.createFeature(featureFolder.toURL(), null, null);
494
495             //We only delete here, so if an exception is thrown the user can still see the retrieve.xml
496
target.delete();
497
498             featureProperties = new Properties();
499             InputStream featureStream = new BufferedInputStream(new FileInputStream(new File(featureFolder, PROPERTIES_FILE)));
500             featureProperties.load(featureStream);
501             featureStream.close();
502             clear(featureFolder);
503             if (feature == null) {
504                 String JavaDoc message = NLS.bind(Messages.exception_missingFeature, elementName);
505                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, null));
506             }
507         } catch (Exception JavaDoc e) {
508             String JavaDoc message = NLS.bind(Messages.error_fetchingFeature, elementName);
509             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, e));
510         }
511     }
512
513     /**
514      * Deletes all the files and directories from the given root down (inclusive).
515      * Returns false if we could not delete some file or an exception occurred
516      * at any point in the deletion.
517      * Even if an exception occurs, a best effort is made to continue deleting.
518      *
519      * @param root
520      * @return boolean
521      */

522     public static boolean clear(File root) {
523         boolean result = true;
524         if (root.isDirectory()) {
525             String JavaDoc[] list = root.list();
526             // for some unknown reason, list() can return null.
527
// Just skip the children If it does.
528
if (list != null)
529                 for (int i = 0; i < list.length; i++)
530                     result &= clear(new java.io.File JavaDoc(root, list[i]));
531         }
532         try {
533             if (root.exists())
534                 result &= root.delete();
535         } catch (Exception JavaDoc e) {
536             // ignore any exceptions
537
result = false;
538         }
539         return result;
540     }
541
542     protected IPath computeFinalLocation(String JavaDoc type, String JavaDoc elementName, Version version) {
543         IPath location = new Path(Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY));
544         if (type.equals(IFetchFactory.ELEMENT_TYPE_FEATURE))
545             location = location.append(DEFAULT_FEATURE_LOCATION);
546         else
547             location = location.append(DEFAULT_PLUGIN_LOCATION);
548         return location.append(elementName + (version.equals(Version.emptyVersion) ? "" : '_' + version.toString())); //$NON-NLS-1$
549
}
550
551     /**
552      * Get information stored in the directory file.
553      *
554      * @param elementName
555      * @return String
556      * @throws CoreException
557      */

558     //There are 3 cases described by the following "table"
559
// what is being asked --> what should be returned (what is in the map file)
560
// 1) id --> id (map: id, id@version)
561
// 2) id + version --> id@version (map: id@version, id@version2)
562
// 3) id --> highest version for the id (map: id@version1, id@version2)
563
// 4) id + version --> id (map: id)
564
// The first two cases are straight lookup cases
565
// The third case is a "fallback case"
566
// The fourth is the backward compatibility case.
567
protected Object JavaDoc[] getRepositoryInfo(String JavaDoc elementName, Version version) throws CoreException {
568         //TODO Need to see if the element name contains plugin, bundle, etc...
569
if (directoryFile == null) {
570             directoryFile = readProperties(directoryLocation, "", IStatus.ERROR); //$NON-NLS-1$
571
}
572
573         String JavaDoc result = null;
574         Version matchedVersion = null;
575         //Here we deal with the simple cases: the looked up element exists as is in the map (cases 1 and 2).
576
if (Version.emptyVersion.equals(version)) {
577             result = (String JavaDoc) directoryFile.get(elementName);
578             matchedVersion = Version.emptyVersion;
579         } else {
580             result = (String JavaDoc) directoryFile.get(elementName + ',' + version.getMajor() + '.' + version.getMinor() + '.' + version.getMicro());
581             matchedVersion = new Version(version.getMajor(), version.getMinor(), version.getMicro());
582             if (result == null) {
583                 result = (String JavaDoc) directoryFile.get(elementName); //case 4
584
matchedVersion = Version.emptyVersion;
585                 if (result != null && version.getQualifier().endsWith(IBuildPropertiesConstants.PROPERTY_QUALIFIER)) {
586                     String JavaDoc message = NLS.bind(Messages.warning_fallBackVersion, elementName + ',' + version.toString(), elementName);
587                     BundleHelper.getDefault().getLog().log(new Status(IStatus.WARNING, PI_PDEBUILD, EXCEPTION_ENTRY_MISSING, message, null));
588                 }
589             }
590         }
591         if (result != null)
592             return new Object JavaDoc[] {result, matchedVersion};
593
594         //Here we start dealing with the case #3.
595
initializeSortedDirectory();
596         //Among all the plug-ins, find all the ones for the given elementName
597
SortedMap candidates = directory.subMap(new MapFileEntry(elementName, Version.emptyVersion), new MapFileEntry(elementName, versionMax));
598         if (candidates.size() == 0)
599             return null;
600
601         Map.Entry bestMatch = null;
602         for (Iterator iterator = candidates.entrySet().iterator(); iterator.hasNext();) {
603             Map.Entry entry = (Map.Entry) iterator.next();
604             MapFileEntry aCandidate = (MapFileEntry) entry.getKey();
605             //Find the exact match
606
if (aCandidate.v.equals(version))
607                 return new String JavaDoc[] {(String JavaDoc) entry.getValue(), version.toString()};
608
609             if (bestMatch != null) {
610                 if (((MapFileEntry) bestMatch.getKey()).v.compareTo(((MapFileEntry) entry.getKey()).v) < 1) {
611                     bestMatch = entry;
612                 }
613             } else {
614                 bestMatch = entry;
615             }
616         }
617         if (!Version.emptyVersion.equals(version)) //The request was for a particular version number and it has not been found
618
return null;
619         return new Object JavaDoc[] {(String JavaDoc) bestMatch.getValue(), ((MapFileEntry) bestMatch.getKey()).v};
620     }
621
622     private static final Version versionMax = new Version(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE);
623
624     private void initializeSortedDirectory() {
625         if (directory != null)
626             return;
627         directory = new TreeMap();
628         for (Iterator iter = directoryFile.entrySet().iterator(); iter.hasNext();) {
629             Map.Entry entry = (Map.Entry) iter.next();
630             String JavaDoc[] entryInfo = Utils.getArrayFromString((String JavaDoc) entry.getKey());
631             if (entryInfo.length == 0)
632                 continue;
633             directory.put(new MapFileEntry(entryInfo[0], entryInfo.length == 2 ? new Version(entryInfo[1]) : Version.emptyVersion), entry.getValue());
634         }
635     }
636
637     public class MapFileEntry implements Comparable JavaDoc {
638         String JavaDoc id;
639         Version v;
640
641         public MapFileEntry(String JavaDoc id, Version v) {
642             this.id = id;
643             this.v = v;
644         }
645
646         public int compareTo(Object JavaDoc o) {
647             if (o instanceof MapFileEntry) {
648                 MapFileEntry entry = (MapFileEntry) o;
649                 int result = id.compareTo(entry.id);
650                 if (result != 0)
651                     return result;
652                 return v.compareTo(entry.v);
653             }
654             return -1;
655         }
656
657         public boolean equals(Object JavaDoc o) {
658             if (o instanceof MapFileEntry) {
659                 MapFileEntry entry = (MapFileEntry) o;
660                 return id.equals(entry.id) && v.equals(entry.v);
661             }
662             return false;
663         }
664     }
665
666     /**
667      * Defines, the XML declaration and Ant project.
668      */

669     protected void generatePrologue() {
670         script.println();
671         script.printComment("Fetch script for " + element); //$NON-NLS-1$
672
script.println();
673         script.printProjectDeclaration("FetchScript", TARGET_FETCH, null); //$NON-NLS-1$
674
script.printProperty(PROPERTY_QUIET, "true"); //$NON-NLS-1$
675
}
676
677     /**
678      * Just ends the script.
679      */

680     protected void generateEpilogue() {
681         script.println();
682         script.printProjectEnd();
683     }
684
685     /**
686      * Generates additional targets submitted by the fetch task factory.
687      */

688     private void generateAdditionalTargets() {
689         for (Iterator iter = encounteredTypeOfRepo.iterator(); iter.hasNext();) {
690             ((IFetchFactory) iter.next()).addTargets(script);
691         }
692     }
693
694     /**
695      * Set the directory location to be the given value.
696      *
697      * @param directoryLocation
698      */

699     public void setDirectoryLocation(String JavaDoc directoryLocation) {
700         this.directoryLocation = directoryLocation;
701     }
702
703     /**
704      * Sets whether children of the current element should be fetched.
705      *
706      * @param fetchChildren
707      */

708     public void setFetchChildren(boolean fetchChildren) {
709         this.fetchChildren = fetchChildren;
710     }
711
712     /**
713      * Sets the CVS tag to use when fetching. This overrides whatever is
714      * in the directory database. This is typically used when doing a nightly
715      * build by setting the tag to HEAD.
716      *
717      * @param value a string CVS tag
718      */

719     public void setFetchTag(Properties value) {
720         fetchTags = value;
721     }
722
723     /**
724      * Sets the CVS tag to use when fetching. This overrides whatever is
725      * in the directory database. This is typically used when doing a nightly
726      * build by setting the tag to HEAD.
727      *
728      * @param value a string CVS tag
729      */

730     public void setFetchTagAsString(String JavaDoc value) {
731         fetchTags = new Properties();
732         String JavaDoc[] entries = Utils.getArrayFromString(value);
733         //Backward compatibility
734
if (entries.length == 1 && (entries[0].indexOf('=') == -1)) {
735             fetchTags.put(CVSFetchTaskFactory.OVERRIDE_TAG, entries[0]);
736             return;
737         }
738         for (int i = 0; i < entries.length; i++) {
739             String JavaDoc[] valueForRepo = Utils.getArrayFromString(entries[i], "="); //$NON-NLS-1$
740
if (valueForRepo == null || valueForRepo.length != 2)
741                 throw new IllegalArgumentException JavaDoc("FetchTag " + entries[i]); //$NON-NLS-1$
742
fetchTags.put(valueForRepo[0], valueForRepo[1]);
743         }
744     }
745
746     /**
747      * Sets the CVS password file location to be the given value.
748      *
749      * @param cvsPassFileLocation the CVS password file location
750      */

751     public void setCvsPassFileLocation(String JavaDoc cvsPassFileLocation) {
752         this.cvsPassFileLocation = cvsPassFileLocation;
753     }
754
755     public void setRecursiveGeneration(boolean recursiveGeneration) {
756         this.recursiveGeneration = recursiveGeneration;
757     }
758
759     private void setDirectory(SortedMap dir) {
760         directory = dir;
761     }
762
763     private void setDirectoryFile(Properties dir) {
764         directoryFile = dir;
765     }
766 }
767
Popular Tags