KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > pde > internal > build > builder > FeatureBuildScriptGenerator


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  * G&H Softwareentwicklung GmbH - internationalization implementation (bug 150933)
11  *******************************************************************************/

12 package org.eclipse.pde.internal.build.builder;
13
14 import java.io.*;
15 import java.net.URL JavaDoc;
16 import java.util.*;
17 import java.util.jar.Attributes JavaDoc;
18 import java.util.jar.Manifest JavaDoc;
19 import org.eclipse.core.runtime.*;
20 import org.eclipse.osgi.service.resolver.BundleDescription;
21 import org.eclipse.osgi.util.NLS;
22 import org.eclipse.pde.build.Constants;
23 import org.eclipse.pde.internal.build.*;
24 import org.eclipse.pde.internal.build.ant.AntScript;
25 import org.eclipse.pde.internal.build.ant.FileSet;
26 import org.eclipse.pde.internal.build.site.BuildTimeFeature;
27 import org.eclipse.pde.internal.build.site.PDEState;
28 import org.eclipse.update.core.*;
29 import org.eclipse.update.core.model.IncludedFeatureReferenceModel;
30 import org.eclipse.update.core.model.URLEntryModel;
31 import org.osgi.framework.Version;
32
33 /**
34  * Generates build.xml script for features.
35  */

36 public class FeatureBuildScriptGenerator extends AbstractBuildScriptGenerator {
37     private static final String JavaDoc COMMENT_START_TAG = "<!--"; //$NON-NLS-1$
38
private static final String JavaDoc COMMENT_END_TAG = "-->"; //$NON-NLS-1$
39
private static final String JavaDoc FEATURE_START_TAG = "<feature";//$NON-NLS-1$
40
private static final String JavaDoc PLUGIN_START_TAG = "<plugin"; //$NON-NLS-1$
41
private static final String JavaDoc FRAGMENT_START_TAG = "<fragment"; //$NON-NLS-1$
42
private static final String JavaDoc VERSION = "version";//$NON-NLS-1$
43
private static final String JavaDoc PLUGIN_VERSION = "plugin-version"; //$NON-NLS-1$
44

45     // The 64 characters that are legal in a version qualifier, in lexicographical order.
46
private static final String JavaDoc BASE_64_ENCODING = "-0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; //$NON-NLS-1$
47

48     private static final int QUALIFIER_SUFFIX_VERSION = 1;
49
50     // GENERATION FLAGS
51
/**
52      * Indicates whether scripts for this feature included features should be
53      * generated.
54      */

55     protected boolean analyseIncludedFeatures = false;
56     /**
57      * Indicates whether scripts for this feature children' should be
58      * generated.
59      */

60     protected boolean analysePlugins = true;
61     /** Indicates whether a source feature should be generated for this feature */
62     protected boolean sourceFeatureGeneration = false;
63     /** Indicates whether the feature is binary */
64     protected boolean binaryFeature = true;
65     /** Indicates if the build scripts files should be produced or not */
66     private boolean scriptGeneration = true;
67
68     //FEATURE RELATED INFORMATION
69
/** The identifier of the feature that the build script is being generated for. */
70     protected String JavaDoc featureIdentifier;
71     protected String JavaDoc searchedVersion;
72     /** Target feature. */
73     protected IFeature feature;
74     /** The featurename with its version number */
75     protected String JavaDoc featureFullName;
76     protected String JavaDoc featureFolderName;
77     protected String JavaDoc featureRootLocation;
78     protected String JavaDoc featureTempFolder;
79     protected Feature sourceFeature;
80     protected PluginEntry sourcePlugin;
81     protected String JavaDoc sourceFeatureFullName;
82     protected String JavaDoc sourceFeatureFullNameVersionned;
83     protected SourceFeatureInformation sourceToGather;
84     protected boolean sourcePluginOnly = false;
85     private String JavaDoc[] extraPlugins = new String JavaDoc[0];
86     private boolean generateJnlp = false;
87     private boolean signJars = false;
88     private boolean generateVersionSuffix = false;
89
90     //Cache the result of compteElements for performance
91
private List computedElements = null;
92     private String JavaDoc customFeatureCallbacks = null;
93     private String JavaDoc customCallbacksBuildpath = null;
94     private String JavaDoc customCallbacksFailOnError = null;
95     private String JavaDoc customCallbacksInheritAll = null;
96     private String JavaDoc product = null;
97     private static final String JavaDoc TEMPLATE = "data"; //$NON-NLS-1$
98

99     public FeatureBuildScriptGenerator() {
100         super();
101     }
102
103     /**
104      * Constructor FeatureBuildScriptGenerator.
105      */

106     public FeatureBuildScriptGenerator(String JavaDoc featureId, String JavaDoc versionId, AssemblyInformation informationGathering) throws CoreException {
107         if (featureId == null) {
108             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, Messages.error_missingFeatureId, null));
109         }
110         this.featureIdentifier = featureId;
111         this.searchedVersion = versionId;
112         assemblyData = informationGathering;
113     }
114
115     /**
116      * Returns a list of BundleDescription objects representing the elements delivered by the feature.
117      *
118      * @return List of BundleDescription
119      * @throws CoreException
120      */

121     protected List computeElements() throws CoreException {
122         if (computedElements != null)
123             return computedElements;
124
125         computedElements = new ArrayList(5);
126         IPluginEntry[] pluginList = feature.getPluginEntries();
127         for (int i = 0; i < pluginList.length; i++) {
128             IPluginEntry entry = pluginList[i];
129             VersionedIdentifier identifier = entry.getVersionedIdentifier();
130             BundleDescription model;
131             if (selectConfigs(entry).size() == 0)
132                 continue;
133
134             String JavaDoc versionRequested = identifier.getVersion().toString();
135             model = getSite(false).getRegistry().getResolvedBundle(identifier.getIdentifier(), versionRequested);
136             //we prefer a newly generated source plugin over a preexisting binary one.
137
if ((model == null || Utils.isBinary(model)) && getBuildProperties().containsKey(GENERATION_SOURCE_PLUGIN_PREFIX + identifier.getIdentifier())) {
138                 generateEmbeddedSource(identifier.getIdentifier());
139                 model = getSite(false).getRegistry().getResolvedBundle(identifier.getIdentifier(), versionRequested);
140             }
141             if (model == null) {
142                 String JavaDoc message = NLS.bind(Messages.exception_missingPlugin, entry.getVersionedIdentifier());
143                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PLUGIN_MISSING, message, null));
144             }
145
146             associateModelAndEntry(model, entry);
147
148             computedElements.add(model);
149             collectElementToAssemble(pluginList[i]);
150             collectSourcePlugins(pluginList[i], model);
151         }
152         return computedElements;
153     }
154
155     private void associateModelAndEntry(BundleDescription model, IPluginEntry entry) {
156         Properties bundleProperties = ((Properties) model.getUserObject());
157         if (bundleProperties == null) {
158             bundleProperties = new Properties();
159             model.setUserObject(bundleProperties);
160         }
161         Set entries = (Set) bundleProperties.get(PLUGIN_ENTRY);
162         if (entries == null) {
163             entries = new HashSet();
164             bundleProperties.put(PLUGIN_ENTRY, entries);
165         }
166         entries.add(entry);
167     }
168
169     private void generateEmbeddedSource(String JavaDoc pluginId) throws CoreException {
170         if (sourceFeatureGeneration)
171             return;
172         FeatureBuildScriptGenerator featureGenerator = new FeatureBuildScriptGenerator(Utils.getArrayFromString(getBuildProperties().getProperty(GENERATION_SOURCE_PLUGIN_PREFIX + pluginId))[0], null, assemblyData);
173         featureGenerator.setGenerateIncludedFeatures(false);
174         featureGenerator.setAnalyseChildren(analysePlugins);
175         featureGenerator.setSourceFeatureId(pluginId);
176         featureGenerator.setSourceFeatureGeneration(true);
177         featureGenerator.setExtraPlugins(Utils.getArrayFromString(getBuildProperties().getProperty(GENERATION_SOURCE_PLUGIN_PREFIX + pluginId)));
178         featureGenerator.setBinaryFeatureGeneration(false);
179         featureGenerator.setScriptGeneration(false);
180         featureGenerator.setPluginPath(pluginPath);
181         featureGenerator.setBuildSiteFactory(siteFactory);
182         featureGenerator.setDevEntries(devEntries);
183         featureGenerator.setCompiledElements(getCompiledElements());
184         featureGenerator.setSourceToGather(sourceToGather);
185         featureGenerator.setSourcePluginOnly(true);
186         featureGenerator.setBuildingOSGi(isBuildingOSGi());
187         featureGenerator.includePlatformIndependent(isPlatformIndependentIncluded());
188         featureGenerator.setIgnoreMissingPropertiesFile(isIgnoreMissingPropertiesFile());
189         featureGenerator.setGenerateVersionSuffix(generateVersionSuffix);
190         featureGenerator.generate();
191     }
192
193     public void setSourcePluginOnly(boolean b) {
194         sourcePluginOnly = b;
195     }
196
197     private void collectSourcePlugins(IPluginEntry pluginEntry, BundleDescription model) {
198         if (!sourceFeatureGeneration)
199             return;
200         //Do not collect plug-ins for which we are not generating build.xml
201
try {
202             if (AbstractScriptGenerator.readProperties(model.getLocation(), PROPERTIES_FILE, IStatus.OK) == MissingProperties.getInstance())
203                 return;
204         } catch (CoreException e) {
205             return;
206         }
207         // The generic entry may not be part of the configuration we are building however,
208
// the code for a non platform specific plugin still needs to go into a generic source plugin
209
if (pluginEntry.getOS() == null && pluginEntry.getWS() == null && pluginEntry.getOSArch() == null) {
210             sourceToGather.addElementEntry(Config.genericConfig(), model);
211             return;
212         }
213         // Here we fan the plugins into the source fragment where they should go
214
List correctConfigs = selectConfigs(pluginEntry);
215         for (Iterator iter = correctConfigs.iterator(); iter.hasNext();) {
216             sourceToGather.addElementEntry((Config) iter.next(), model);
217         }
218     }
219
220     /**
221      * Set the boolean for whether or not children scripts should be generated.
222      *
223      * @param generate
224      * <code>true</code> if the children scripts should be
225      * generated, <code>false</code> otherwise
226      */

227     public void setAnalyseChildren(boolean generate) {
228         analysePlugins = generate;
229     }
230
231     /**
232      * @see AbstractScriptGenerator#generate()
233      */

234     public void generate() throws CoreException {
235         String JavaDoc message;
236         if (workingDirectory == null) {
237             throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_BUILDDIRECTORY_LOCATION_MISSING, Messages.error_missingInstallLocation, null));
238         }
239         initializeVariables();
240
241         // if the feature defines its own custom script, we do not generate a
242
// new one but we do try to update the version number
243
boolean custom = TRUE.equalsIgnoreCase((String JavaDoc) getBuildProperties().get(PROPERTY_CUSTOM));
244         File customBuildFile = null;
245         if (custom) {
246             customBuildFile = new File(featureRootLocation, DEFAULT_BUILD_SCRIPT_FILENAME);
247             if (!customBuildFile.exists()) {
248                 message = NLS.bind(Messages.error_missingCustomBuildFile, customBuildFile);
249                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, null));
250             }
251
252             //turn off script generation so we don't overwrite the custom script
253
scriptGeneration = false;
254             
255             /* need to do root files here because we won't be doing the gatherBinParts where it normally happens */
256             List configs = getConfigInfos();
257             for (Iterator iter = configs.iterator(); iter.hasNext();) {
258                 assemblyData.addRootFileProvider((Config) iter.next(), feature);
259             }
260         }
261         if (analyseIncludedFeatures)
262             generateIncludedFeatureBuildFile();
263         if (sourceFeatureGeneration)
264             generateSourceFeature();
265         if (analysePlugins)
266             generateChildrenScripts();
267         if (sourceFeatureGeneration) {
268             addSourceFragmentsToFeature();
269             writeSourceFeature();
270         }
271         if (!sourcePluginOnly)
272             collectElementToAssemble(feature);
273
274         // Do the recursive generation of build files for the features required by the current feature
275
if (sourceFeatureGeneration)
276             generateSourceFeatureScripts();
277             
278         if (custom) {
279             //Feature had a custom build script, we need to update the version in it.
280
//Do it here after generateChildrenScripts since there may have been a suffix generated.
281
try {
282                 updateVersion(customBuildFile, PROPERTY_FEATURE_VERSION_SUFFIX, feature.getVersionedIdentifier().getVersion().toString());
283             } catch (IOException e) {
284                 message = NLS.bind(Messages.exception_writeScript, customBuildFile);
285                 throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, e));
286             }
287         }
288
289         if (scriptGeneration) {
290             openScript(featureRootLocation, DEFAULT_BUILD_SCRIPT_FILENAME);
291             try {
292                 generateBuildScript();
293             } finally {
294                 closeScript();
295             }
296         }
297     }
298
299     protected void generateIncludedFeatureBuildFile() throws CoreException {
300         IIncludedFeatureReference[] referencedFeatures = feature.getIncludedFeatureReferences();
301         for (int i = 0; i < referencedFeatures.length; i++) {
302             String JavaDoc featureId = ((IncludedFeatureReferenceModel) referencedFeatures[i]).getFeatureIdentifier();
303             String JavaDoc featureVersion = ((IncludedFeatureReferenceModel) referencedFeatures[i]).getFeatureVersion();
304             //If the feature which is included is a source feature, then instead of calling the generation of the featureID we are
305
// calling the generation of the corresponding binary feature but without generating the scripts (set binaryFeatureGeneration to false)
306
boolean doSourceFeatureGeneration = getBuildProperties().containsKey(GENERATION_SOURCE_FEATURE_PREFIX + featureId);
307             FeatureBuildScriptGenerator generator = new FeatureBuildScriptGenerator(doSourceFeatureGeneration == true ? Utils.getArrayFromString(getBuildProperties().getProperty(GENERATION_SOURCE_FEATURE_PREFIX + featureId))[0] : featureId, featureVersion, assemblyData);
308             //If we are generating a source feature we don't want to go recursively
309
generator.setGenerateIncludedFeatures(doSourceFeatureGeneration ? false : true);
310             generator.setAnalyseChildren(analysePlugins);
311             generator.setSourceFeatureGeneration(doSourceFeatureGeneration);
312             generator.setBinaryFeatureGeneration(!doSourceFeatureGeneration);
313             //We don't want to regenerate the scripts for the binary feature we are reading to build the source feature
314
generator.setScriptGeneration(doSourceFeatureGeneration ? false : true);
315             if (doSourceFeatureGeneration) {
316                 generator.setSourceFeatureId(featureId);
317                 generator.setExtraPlugins(Utils.getArrayFromString(getBuildProperties().getProperty(GENERATION_SOURCE_FEATURE_PREFIX + featureId)));
318             }
319             generator.setPluginPath(pluginPath);
320             generator.setBuildSiteFactory(siteFactory);
321             generator.setDevEntries(devEntries);
322             generator.setCompiledElements(getCompiledElements());
323             generator.setSourceToGather(new SourceFeatureInformation());
324             generator.setBuildingOSGi(isBuildingOSGi());
325             generator.includePlatformIndependent(isPlatformIndependentIncluded());
326             generator.setIgnoreMissingPropertiesFile(isIgnoreMissingPropertiesFile());
327             generator.setGenerateVersionSuffix(generateVersionSuffix);
328             try {
329                 generator.generate();
330             } catch (CoreException exception) {
331                 absorbExceptionIfOptionalFeature(referencedFeatures[i], exception);
332             }
333         }
334     }
335
336     private void absorbExceptionIfOptionalFeature(IIncludedFeatureReference feature, CoreException toAbsorb) throws CoreException {
337         if (toAbsorb.getStatus().getCode() != EXCEPTION_FEATURE_MISSING || (toAbsorb.getStatus().getCode() == EXCEPTION_FEATURE_MISSING && !feature.isOptional()))
338             throw toAbsorb;
339     }
340
341     protected void setExtraPlugins(String JavaDoc[] plugins) {
342         extraPlugins = plugins;
343     }
344
345     /**
346      * Main call for generating the script.
347      *
348      * @throws CoreException
349      */

350     private void generateBuildScript() throws CoreException {
351         if (BundleHelper.getDefault().isDebugging())
352             System.out.println("Generating feature " + featureFullName); //$NON-NLS-1$
353
generatePrologue();
354         generateAllPluginsTarget();
355         generateAllFeaturesTarget();
356         generateUpdateFeatureFile();
357         generateAllChildrenTarget();
358         generateChildrenTarget();
359         generateBuildJarsTarget();
360         generateBuildZipsTarget();
361         generateBuildUpdateJarTarget();
362         generateGatherBinPartsTarget();
363         generateZipDistributionWholeTarget();
364         generateZipSourcesTarget();
365         generateZipLogsTarget();
366         generateCleanTarget();
367         generateRefreshTarget();
368         generateGatherSourcesTarget();
369         generateGatherLogsTarget();
370         generateEpilogue();
371     }
372
373     /**
374      * Method generateGatherSource. Used to enable the recursive call of
375      * gathering the sources for the features
376      */

377     private void generateGatherSourcesTarget() {
378         script.printTargetDeclaration(TARGET_GATHER_SOURCES, null, null, null, null);
379         Map params = new HashMap(2);
380         params.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_FEATURE_TEMP_FOLDER) + '/' + DEFAULT_PLUGIN_LOCATION + '/' + sourceFeatureFullNameVersionned + '/' + "src"); //$NON-NLS-1$
381
params.put(PROPERTY_TARGET, TARGET_GATHER_SOURCES);
382         script.printAntCallTask(TARGET_CHILDREN, true, params);
383         script.printTargetEnd();
384     }
385
386     /**
387      * Method generateGatherSource. Used to enable the recursive call of
388      * gathering the sources for the features
389      */

390     private void generateGatherLogsTarget() {
391         script.println();
392         script.printTargetDeclaration(TARGET_GATHER_LOGS, TARGET_INIT, null, null, null);
393         script.printMkdirTask(featureTempFolder);
394         Map params = new HashMap(1);
395         params.put(PROPERTY_TARGET, TARGET_GATHER_LOGS);
396         params.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(featureTempFolder).append(DEFAULT_PLUGIN_LOCATION).toString());
397         script.printAntCallTask(TARGET_ALL_CHILDREN, false, params); //$NON-NLS-1$
398
script.printTargetEnd();
399     }
400
401     private void generateUpdateFeatureFile() {
402         script.printTargetDeclaration(TARGET_UPDATE_FEATURE_FILE, TARGET_INIT, null, null, null);
403         script.printTargetEnd();
404     }
405
406     /**
407      * Add the <code>build.zips</code> target to the given Ant script.
408      *
409      * @throws CoreException
410      */

411     private void generateBuildZipsTarget() throws CoreException {
412         StringBuffer JavaDoc zips = new StringBuffer JavaDoc();
413         Properties props = getBuildProperties();
414         for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
415             Map.Entry entry = (Map.Entry) iterator.next();
416             String JavaDoc key = (String JavaDoc) entry.getKey();
417             if (key.startsWith(PROPERTY_SOURCE_PREFIX) && key.endsWith(PROPERTY_ZIP_SUFFIX)) {
418                 String JavaDoc zipName = key.substring(PROPERTY_SOURCE_PREFIX.length());
419                 zips.append(',');
420                 zips.append(zipName);
421                 generateZipIndividualTarget(zipName, (String JavaDoc) entry.getValue());
422             }
423         }
424         script.println();
425         script.printTargetDeclaration(TARGET_BUILD_ZIPS, TARGET_INIT + zips.toString(), null, null, null);
426         Map params = new HashMap(2);
427         params.put(PROPERTY_TARGET, TARGET_BUILD_ZIPS);
428         script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
429         script.printTargetEnd();
430     }
431
432     /**
433      * Add a <code>zip</code> target to the given Ant script.
434      *
435      * @param zipName the name of the zip file to create
436      * @param source the directory name to read the files from
437      */

438     private void generateZipIndividualTarget(String JavaDoc zipName, String JavaDoc source) {
439         script.println();
440         script.printTargetDeclaration(zipName, TARGET_INIT, null, null, null);
441         script.printZipTask(Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + zipName, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + source, false, false, null);
442         script.printTargetEnd();
443     }
444
445     /**
446      * Add the <code>clean</code> target to the given Ant script.
447      */

448     private void generateCleanTarget() {
449         script.println();
450         script.printTargetDeclaration(TARGET_CLEAN, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_clean, featureIdentifier));
451         script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".jar", null); //$NON-NLS-1$
452
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".bin.dist.zip", null); //$NON-NLS-1$
453
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".log.zip", null); //$NON-NLS-1$
454
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".src.zip", null); //$NON-NLS-1$
455
script.printDeleteTask(featureTempFolder, null, null);
456         Map params = new HashMap(2);
457         params.put(PROPERTY_TARGET, TARGET_CLEAN);
458         script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
459         script.printTargetEnd();
460     }
461
462     /**
463      * Add the <code>zip.logs</code> target to the given Ant script.
464      */

465     private void generateZipLogsTarget() {
466         script.println();
467         script.printTargetDeclaration(TARGET_ZIP_LOGS, TARGET_INIT, null, null, null);
468         script.printDeleteTask(featureTempFolder, null, null);
469         script.printMkdirTask(featureTempFolder);
470         Map params = new HashMap(1);
471         params.put(PROPERTY_INCLUDE_CHILDREN, "true"); //$NON-NLS-1$
472
params.put(PROPERTY_TARGET, TARGET_GATHER_LOGS);
473         params.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(featureTempFolder).append(DEFAULT_PLUGIN_LOCATION).toString());
474         script.printAntCallTask(TARGET_ALL_CHILDREN, false, params); //$NON-NLS-1$
475
IPath destination = new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION)).append(featureFullName + ".log.zip"); //$NON-NLS-1$
476
script.printZipTask(destination.toString(), featureTempFolder, true, false, null);
477         script.printDeleteTask(featureTempFolder, null, null);
478         script.printTargetEnd();
479     }
480
481     /**
482      * Add the <code>zip.sources</code> target to the given Ant script.
483      */

484     protected void generateZipSourcesTarget() {
485         script.println();
486         script.printTargetDeclaration(TARGET_ZIP_SOURCES, TARGET_INIT, null, null, null);
487         script.printDeleteTask(featureTempFolder, null, null);
488         script.printMkdirTask(featureTempFolder);
489         Map params = new HashMap(1);
490         params.put(PROPERTY_INCLUDE_CHILDREN, "true"); //$NON-NLS-1$
491
params.put(PROPERTY_TARGET, TARGET_GATHER_SOURCES);
492         params.put(PROPERTY_DESTINATION_TEMP_FOLDER, featureTempFolder + '/' + DEFAULT_PLUGIN_LOCATION + '/' + sourceFeatureFullNameVersionned + '/' + "src"); //$NON-NLS-1$
493
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
494         script.printZipTask(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".src.zip", featureTempFolder, true, false, null); //$NON-NLS-1$
495
script.printDeleteTask(featureTempFolder, null, null);
496         script.printTargetEnd();
497     }
498
499     /**
500      * Add the <code>gather.bin.parts</code> target to the given Ant script
501      *
502      * @throws CoreException
503      */

504     private void generateGatherBinPartsTarget() throws CoreException {
505         String JavaDoc include = (String JavaDoc) getBuildProperties().get(PROPERTY_BIN_INCLUDES);
506         String JavaDoc exclude = (String JavaDoc) getBuildProperties().get(PROPERTY_BIN_EXCLUDES);
507         String JavaDoc root = Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + featureFolderName;
508
509         script.println();
510         script.printTargetDeclaration(TARGET_GATHER_BIN_PARTS, TARGET_INIT, PROPERTY_FEATURE_BASE, null, null);
511         if (include != null)
512             script.printMkdirTask(root);
513
514         Map callbackParams = null;
515         if (customFeatureCallbacks != null) {
516             callbackParams = new HashMap(1);
517             callbackParams.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE)).append(DEFAULT_PLUGIN_LOCATION).toString());
518             callbackParams.put(PROPERTY_FEATURE_DIRECTORY, root);
519             script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
520         }
521
522         Map params = new HashMap(1);
523         params.put(PROPERTY_TARGET, TARGET_GATHER_BIN_PARTS);
524         params.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE)).append(DEFAULT_PLUGIN_LOCATION).toString());
525         script.printAntCallTask(TARGET_CHILDREN, true, params);
526
527         if (include != null) {
528             if (include != null || exclude != null) {
529                 FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, include, null, exclude, null, null);
530                 script.printCopyTask(null, root, new FileSet[] {fileSet}, true, false);
531             }
532             // Generate the parameters for the Id Replacer.
533
String JavaDoc featureVersionInfo = ""; //$NON-NLS-1$
534
// Here we get all the included features (independently of the config being built so the version numbers in the feature can be replaced)
535
IIncludedFeatureReference[] includedFeatures = feature.getRawIncludedFeatureReferences();
536             for (int i = 0; i < includedFeatures.length; i++) {
537                 String JavaDoc versionRequested = includedFeatures[i].getVersionedIdentifier().getVersion().toString();
538                 IFeature includedFeature = null;
539                 try {
540                     includedFeature = getSite(false).findFeature(includedFeatures[i].getVersionedIdentifier().getIdentifier(), versionRequested, true);
541                 } catch (CoreException e) {
542                     absorbExceptionIfOptionalFeature(includedFeatures[i], e);
543                     continue;
544                 }
545                 VersionedIdentifier includedFeatureVersionId = includedFeature.getVersionedIdentifier();
546                 if (needsReplacement(versionRequested))
547                     featureVersionInfo += (includedFeatureVersionId.getIdentifier() + ':' + extract3Segments(versionRequested) + ',' + includedFeatureVersionId.getVersion().toString() + ',');
548             }
549             String JavaDoc pluginVersionInfo = ""; //$NON-NLS-1$
550
// Here we get all the included plugins (independently of the config being built so the version numbers in the feature can be replaced)
551
IPluginEntry[] pluginsIncluded = feature.getRawPluginEntries();
552             for (int i = 0; i < pluginsIncluded.length; i++) {
553                 VersionedIdentifier identifier = pluginsIncluded[i].getVersionedIdentifier();
554                 BundleDescription model;
555                 // If we ask for 0.0.0, the call to the registry must have null as a parameter
556
String JavaDoc versionRequested = identifier.getVersion().toString();
557                 String JavaDoc entryIdentifier = identifier.getIdentifier();
558                 model = getSite(false).getRegistry().getResolvedBundle(entryIdentifier, versionRequested);
559                 if (model != null) {
560                     if (needsReplacement(versionRequested))
561                         pluginVersionInfo += (entryIdentifier + ':' + extract3Segments(versionRequested) + ',' + model.getVersion() + ',');
562                 }
563             }
564             script.println("<eclipse.idReplacer featureFilePath=\"" + AntScript.getEscaped(root) + '/' + Constants.FEATURE_FILENAME_DESCRIPTOR + "\" selfVersion=\"" + feature.getVersionedIdentifier().getVersion() + "\" featureIds=\"" + featureVersionInfo + "\" pluginIds=\"" + pluginVersionInfo + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
565
}
566         generateRootFilesAndPermissionsCalls();
567         if (customFeatureCallbacks != null) {
568             script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
569         }
570         script.printTargetEnd();
571         generateRootFilesAndPermissions();
572     }
573
574     private boolean needsReplacement(String JavaDoc s) {
575         if (s.equalsIgnoreCase(GENERIC_VERSION_NUMBER) || s.endsWith(PROPERTY_QUALIFIER))
576             return true;
577         return false;
578     }
579
580     private Version extract3Segments(String JavaDoc s) {
581         Version tmp = new Version(s);
582         return new Version(tmp.getMajor(), tmp.getMinor(), tmp.getMicro());
583     }
584
585     /**
586      *
587      */

588     private void generateRootFilesAndPermissionsCalls() {
589         script.printAntCallTask(TARGET_ROOTFILES_PREFIX + Utils.getPropertyFormat(PROPERTY_OS) + '_' + Utils.getPropertyFormat(PROPERTY_WS) + '_' + Utils.getPropertyFormat(PROPERTY_ARCH), true, null);
590     }
591
592     /**
593      *
594      */

595     private void generateRootFilesAndPermissions() throws CoreException {
596         if (product != null && !havePDEUIState()) {
597             ProductGenerator generator = new ProductGenerator();
598             generator.setProduct(product);
599             generator.setBuildSiteFactory(siteFactory);
600             generator.setBuildProperties(getBuildProperties());
601             generator.setRoot(featureRootLocation);
602             generator.setWorkingDirectory(getWorkingDirectory());
603             try {
604                 generator.generate();
605             } catch (CoreException e) {
606                 //problem with the .product file
607
//TODO Log warning/error
608
}
609         }
610         for (Iterator iter = getConfigInfos().iterator(); iter.hasNext();) {
611             Config aConfig = (Config) iter.next();
612             script.printTargetDeclaration(TARGET_ROOTFILES_PREFIX + aConfig.toString("_"), null, null, null, null); //$NON-NLS-1$
613
generateCopyRootFiles(aConfig);
614             Utils.generatePermissions(getBuildProperties(), aConfig, PROPERTY_FEATURE_BASE, script);
615             script.printTargetEnd();
616         }
617         script.printTargetDeclaration(TARGET_ROOTFILES_PREFIX + "group_group_group", null, null, null, null); //$NON-NLS-1$
618
for (Iterator iter = getConfigInfos().iterator(); iter.hasNext();) {
619             Config aConfig = (Config) iter.next();
620             script.printAntCallTask(TARGET_ROOTFILES_PREFIX + aConfig.toString("_"), true, null);//.getPropertyFormat(PROPERTY_OS) + '_' + Utils.getPropertyFormat(PROPERTY_WS) + '_' + Utils.getPropertyFormat(PROPERTY_ARCH))
621
}
622         script.printTargetEnd();
623     }
624
625     private void generateCopyRootFiles(Config aConfig) throws CoreException {
626         Properties properties = getBuildProperties();
627         Map foldersToCopy = new HashMap(2);
628
629         /* normal root files */
630         String JavaDoc baseList = getBuildProperties().getProperty(ROOT, ""); //$NON-NLS-1$
631
String JavaDoc fileList = getBuildProperties().getProperty(ROOT_PREFIX + aConfig.toString("."), ""); //$NON-NLS-1$ //$NON-NLS-2$
632
fileList = (fileList.length() == 0 ? "" : fileList + ',') + baseList; //$NON-NLS-1$
633
if (fileList.length() > 0)
634             foldersToCopy.put("", fileList); //$NON-NLS-1$
635

636         /* root files going to subfolders */
637         String JavaDoc configPrefix = ROOT_PREFIX + aConfig.toString(".") + FOLDER_INFIX; //$NON-NLS-1$
638
for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
639             String JavaDoc key = (String JavaDoc) it.next();
640             String JavaDoc folder = null;
641             if (key.startsWith(ROOT_FOLDER_PREFIX)) {
642                 folder = key.substring(ROOT_FOLDER_PREFIX.length(), key.length());
643             } else if (key.startsWith(configPrefix)) {
644                 folder = key.substring(configPrefix.length(), key.length());
645             }
646             if (folder != null) {
647                 String JavaDoc value = properties.getProperty(key);
648                 if (foldersToCopy.containsKey(folder)) {
649                     String JavaDoc set = (String JavaDoc) foldersToCopy.get(folder);
650                     set += "," + value; //$NON-NLS-1$
651
foldersToCopy.put(folder, set);
652                 } else {
653                     foldersToCopy.put(folder, value);
654                 }
655             }
656         }
657
658         if (foldersToCopy.isEmpty())
659             return;
660
661         String JavaDoc configName = aConfig.toStringReplacingAny(".", ANY_STRING); //$NON-NLS-1$
662
String JavaDoc shouldOverwrite = properties.getProperty(PROPERTY_OVERWRITE_ROOTFILES, "true"); //$NON-NLS-1$
663
boolean overwrite = Boolean.valueOf(shouldOverwrite).booleanValue();
664
665         assemblyData.addRootFileProvider(aConfig, feature);
666
667         Object JavaDoc[] folders = foldersToCopy.keySet().toArray();
668         for (int i = 0; i < folders.length; i++) {
669             String JavaDoc folder = (String JavaDoc) folders[i];
670             fileList = (String JavaDoc) foldersToCopy.get(folder);
671             String JavaDoc[] files = Utils.getArrayFromString(fileList, ","); //$NON-NLS-1$
672
FileSet[] fileSet = new FileSet[files.length];
673             for (int j = 0; j < files.length; j++) {
674                 String JavaDoc file = files[j];
675                 String JavaDoc fromDir = Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/';
676                 if (file.startsWith("absolute:")) { //$NON-NLS-1$
677
file = file.substring(9);
678                     fromDir = ""; //$NON-NLS-1$
679
}
680                 if (file.startsWith("file:")) { //$NON-NLS-1$
681
IPath target = new Path(file.substring(5));
682                     fileSet[j] = new FileSet(fromDir + target.removeLastSegments(1), null, target.lastSegment(), null, null, null, null);
683                 } else {
684                     fileSet[j] = new FileSet(fromDir + file, null, "**", null, null, null, null); //$NON-NLS-1$
685
}
686             }
687             script.printMkdirTask(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + configName + '/' + Utils.getPropertyFormat(PROPERTY_COLLECTING_FOLDER) + '/' + folder);
688             script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + configName + '/' + Utils.getPropertyFormat(PROPERTY_COLLECTING_FOLDER) + '/' + folder, fileSet, true, overwrite);
689         }
690     }
691
692     /**
693      * Add the <code>build.update.jar</code> target to the given script.
694      */

695     private void generateBuildUpdateJarTarget() {
696         script.println();
697         script.printTargetDeclaration(TARGET_BUILD_UPDATE_JAR, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_buildUpdateJar, featureIdentifier));
698         Map params = new HashMap(1);
699         params.put(PROPERTY_TARGET, TARGET_BUILD_UPDATE_JAR);
700         script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
701         script.printProperty(PROPERTY_FEATURE_BASE, featureTempFolder);
702         script.printDeleteTask(featureTempFolder, null, null);
703         script.printMkdirTask(featureTempFolder);
704         params.clear();
705         params.put(PROPERTY_FEATURE_BASE, featureTempFolder);
706         params.put(PROPERTY_OS, feature.getOS() == null ? Config.ANY : feature.getOS());
707         params.put(PROPERTY_WS, feature.getWS() == null ? Config.ANY : feature.getWS());
708         params.put(PROPERTY_ARCH, feature.getOSArch() == null ? Config.ANY : feature.getOSArch());
709         params.put(PROPERTY_NL, feature.getNL() == null ? Config.ANY : feature.getNL());
710         // Be sure to call the gather with children turned off. The only way to
711
// do this is
712
// to clear all inherited values. Must remember to setup anything that
713
// is really expected.
714
script.printAntCallTask(TARGET_GATHER_BIN_PARTS, false, params);
715         String JavaDoc jar = Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".jar"; //$NON-NLS-1$
716
script.printJarTask(jar, featureTempFolder + '/' + featureFolderName, null);
717         script.printDeleteTask(featureTempFolder, null, null);
718         if (generateJnlp)
719             script.println("<eclipse.jnlpGenerator feature=\"" + AntScript.getEscaped(jar) + "\" codebase=\"" + Utils.getPropertyFormat(IXMLConstants.PROPERTY_JNLP_CODEBASE) + "\" j2se=\"" + Utils.getPropertyFormat(IXMLConstants.PROPERTY_JNLP_J2SE) + "\" locale=\"" + Utils.getPropertyFormat(IXMLConstants.PROPERTY_JNLP_LOCALE) + "\" generateOfflineAllowed=\"" + Utils.getPropertyFormat(PROPERTY_JNLP_GENOFFLINE) + "\" configInfo=\"" + Utils.getPropertyFormat(PROPERTY_JNLP_CONFIGS) + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
720
if (signJars) {
721             if (generateJnlp) {
722                 script.printProperty(PROPERTY_UNSIGN, "true"); //$NON-NLS-1$
723
}
724             script.println("<eclipse.jarProcessor sign=\"" + Utils.getPropertyFormat(PROPERTY_SIGN) + "\" pack=\"" + Utils.getPropertyFormat(PROPERTY_PACK)+ "\" unsign=\"" + Utils.getPropertyFormat(PROPERTY_UNSIGN) + "\" jar=\"" + AntScript.getEscaped(jar) + "\" alias=\"" + Utils.getPropertyFormat(PROPERTY_SIGN_ALIAS) + "\" keystore=\"" + Utils.getPropertyFormat(PROPERTY_SIGN_KEYSTORE) + "\" storepass=\"" + Utils.getPropertyFormat(PROPERTY_SIGN_STOREPASS) + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
725
}
726         script.printTargetEnd();
727     }
728
729     /**
730      * Add the <code>zip.distribution</code> target to the given Ant script.
731      * Zip up the whole feature.
732      */

733     protected void generateZipDistributionWholeTarget() {
734         script.println();
735         script.printTargetDeclaration(TARGET_ZIP_DISTRIBUTION, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_zips, featureIdentifier));
736         script.printDeleteTask(featureTempFolder, null, null);
737         script.printMkdirTask(featureTempFolder);
738         Map params = new HashMap(1);
739         params.put(PROPERTY_FEATURE_BASE, featureTempFolder);
740         params.put(PROPERTY_INCLUDE_CHILDREN, TRUE);
741         params.put(PROPERTY_OS, feature.getOS() == null ? Config.ANY : feature.getOS());
742         params.put(PROPERTY_WS, feature.getWS() == null ? Config.ANY : feature.getWS());
743         params.put(PROPERTY_ARCH, feature.getOSArch() == null ? Config.ANY : feature.getOSArch());
744         params.put(PROPERTY_NL, feature.getNL() == null ? Config.ANY : feature.getNL());
745         script.printAntCallTask(TARGET_GATHER_BIN_PARTS, true, params);
746         script.printZipTask(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".bin.dist.zip", featureTempFolder, false, false, null); //$NON-NLS-1$
747
script.printDeleteTask(featureTempFolder, null, null);
748         script.printTargetEnd();
749     }
750
751     /**
752      * Executes a given target in all children's script files.
753      */

754     private void generateAllChildrenTarget() {
755         StringBuffer JavaDoc depends = new StringBuffer JavaDoc();
756         depends.append(TARGET_INIT);
757         depends.append(',');
758         depends.append(TARGET_ALL_FEATURES);
759         depends.append(',');
760         depends.append(TARGET_ALL_PLUGINS);
761         depends.append(',');
762         depends.append(TARGET_UPDATE_FEATURE_FILE);
763         script.println();
764         script.printTargetDeclaration(TARGET_ALL_CHILDREN, depends.toString(), null, null, null);
765         script.printTargetEnd();
766     }
767
768     /**
769      * Target responsible for delegating target calls to plug-in's build.xml
770      * scripts. Plugins are sorted according to the requires chain. Fragments
771      * are inserted afterward
772      *
773      * @throws CoreException
774      */

775     protected void generateAllPluginsTarget() throws CoreException {
776         List plugins = computeElements();
777         plugins = Utils.extractPlugins(getSite(false).getRegistry().getSortedBundles(), plugins);
778         script.println();
779         script.printTargetDeclaration(TARGET_ALL_PLUGINS, TARGET_INIT, null, null, null);
780         Set writtenCalls = new HashSet(plugins.size());
781         for (Iterator iter = plugins.iterator(); iter.hasNext();) {
782             BundleDescription current = (BundleDescription) iter.next();
783             //If it is not a compiled element, then we don't generate a call
784
Properties bundleProperties = (Properties) current.getUserObject();
785             if (bundleProperties == null || bundleProperties.get(IS_COMPILED) == null || bundleProperties.get(IS_COMPILED) == Boolean.FALSE)
786                 continue;
787             // Get the os / ws / arch to pass as a parameter to the plugin
788
if (writtenCalls.contains(current))
789                 continue;
790             writtenCalls.add(current);
791             IPluginEntry[] entries = Utils.getPluginEntry(feature, current.getSymbolicName(), false); //TODO This can be improved to use the value from the user object in the bundleDescription
792
for (int j = 0; j < entries.length; j++) {
793                 List list = selectConfigs(entries[j]);
794                 if (list.size() == 0)
795                     continue;
796                 Map params = null;
797                 Config aMatchingConfig = (Config) list.get(0);
798                 params = new HashMap(3);
799                 if (!aMatchingConfig.getOs().equals(Config.ANY))
800                     params.put(PROPERTY_OS, aMatchingConfig.getOs());
801                 if (!aMatchingConfig.getWs().equals(Config.ANY))
802                     params.put(PROPERTY_WS, aMatchingConfig.getWs());
803                 if (!aMatchingConfig.getArch().equals(Config.ANY))
804                     params.put(PROPERTY_ARCH, aMatchingConfig.getArch());
805                 IPath location = Utils.makeRelative(new Path(getLocation(current)), new Path(featureRootLocation));
806                 script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toString(), Utils.getPropertyFormat(PROPERTY_TARGET), null, null, params);
807             }
808         }
809         script.printTargetEnd();
810     }
811
812     private void generateAllFeaturesTarget() throws CoreException {
813         script.printTargetDeclaration(TARGET_ALL_FEATURES, TARGET_INIT, null, null, null);
814         if (analyseIncludedFeatures) {
815             IIncludedFeatureReference[] features = feature.getIncludedFeatureReferences();
816             for (int i = 0; i < features.length; i++) {
817                 String JavaDoc featureId = features[i].getVersionedIdentifier().getIdentifier();
818                 String JavaDoc versionId = features[i].getVersionedIdentifier().getVersion().toString();
819                 IFeature includedFeature = getSite(false).findFeature(featureId, versionId, false);
820                 if (includedFeature == null) {
821                     if (features[i].isOptional())
822                         continue;
823                     String JavaDoc message = NLS.bind(Messages.exception_missingFeature, featureId + ' ' + versionId);
824                     throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, null));
825                 }
826                 if (includedFeature instanceof BuildTimeFeature) {
827                     if (((BuildTimeFeature) includedFeature).isBinary())
828                         continue;
829                 }
830
831                 String JavaDoc includedFeatureDirectory = includedFeature.getURL().getPath();
832                 int j = includedFeatureDirectory.lastIndexOf(Constants.FEATURE_FILENAME_DESCRIPTOR);
833                 if (j != -1)
834                     includedFeatureDirectory = includedFeatureDirectory.substring(0, j);
835                 IPath location;
836                 location = Utils.makeRelative(new Path(includedFeatureDirectory), new Path(featureRootLocation));
837                 script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toString(), Utils.getPropertyFormat(PROPERTY_TARGET), null, null, null);
838             }
839         }
840         script.printTargetEnd();
841     }
842
843     /**
844      * Just ends the script.
845      */

846     private void generateEpilogue() {
847         script.println();
848         script.printProjectEnd();
849     }
850
851     /**
852      * Defines, the XML declaration, Ant project and init target.
853      */

854     private void generatePrologue() {
855         script.printProjectDeclaration(feature.getVersionedIdentifier().getIdentifier(), TARGET_BUILD_UPDATE_JAR, "."); //$NON-NLS-1$
856
script.println();
857         script.printTargetDeclaration(TARGET_INIT, null, null, null, null);
858         script.printProperty(PROPERTY_FEATURE_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + PROPERTY_FEATURE_TEMP_FOLDER);
859         script.printProperty(PROPERTY_FEATURE_DESTINATION, Utils.getPropertyFormat(PROPERTY_BASEDIR));
860         if (customFeatureCallbacks != null) {
861             script.printAvailableTask(PROPERTY_CUSTOM_BUILD_CALLBACKS, customCallbacksBuildpath + '/' + customFeatureCallbacks, customFeatureCallbacks);
862         }
863         script.printTargetEnd();
864     }
865
866     /**
867      * @throws CoreException
868      */

869     private void generateChildrenScripts() throws CoreException {
870         List plugins = computeElements();
871         String JavaDoc suffix = generateFeatureVersionSuffix((BuildTimeFeature) feature);
872         if (suffix != null) {
873             PluginVersionIdentifier versionId = feature.getVersionedIdentifier().getVersion();
874             String JavaDoc qualifier = versionId.getQualifierComponent();
875             qualifier = qualifier.substring(0, ((BuildTimeFeature) feature).getContextQualifierLength());
876             qualifier = qualifier + '-' + suffix;
877             versionId = new PluginVersionIdentifier(versionId.getMajorComponent(), versionId.getMinorComponent(), versionId.getServiceComponent(), qualifier);
878             String JavaDoc newVersion = versionId.toString();
879             ((BuildTimeFeature) feature).setFeatureVersion(newVersion);
880             initializeFeatureNames(); //reset our variables
881
}
882         generateModels(Utils.extractPlugins(getSite(false).getRegistry().getSortedBundles(), plugins));
883     }
884
885     // Integer to character conversion in our base-64 encoding scheme. If the
886
// input is out of range, an illegal character will be returned.
887
private static char base64Character(int number) {
888         if (number < 0 || number > 63) {
889             return ' ';
890         }
891         return BASE_64_ENCODING.charAt(number);
892     }
893
894     // Encode a non-negative number as a variable length string, with the
895
// property that if X > Y then the encoding of X is lexicographically
896
// greater than the enocding of Y. This is accomplished by encoding the
897
// length of the string at the beginning of the string. The string is a
898
// series of base 64 (6-bit) characters. The first three bits of the first
899
// character indicate the number of additional characters in the string.
900
// The last three bits of the first character and all of the rest of the
901
// characters encode the actual value of the number. Examples:
902
// 0 --> 000 000 --> "-"
903
// 7 --> 000 111 --> "6"
904
// 8 --> 001 000 001000 --> "77"
905
// 63 --> 001 000 111111 --> "7z"
906
// 64 --> 001 001 000000 --> "8-"
907
// 511 --> 001 111 111111 --> "Dz"
908
// 512 --> 010 000 001000 000000 --> "E7-"
909
// 2^32 - 1 --> 101 011 111111 ... 111111 --> "fzzzzz"
910
// 2^45 - 1 --> 111 111 111111 ... 111111 --> "zzzzzzzz"
911
// (There are some wasted values in this encoding. For example,
912
// "7-" through "76" and "E--" through "E6z" are not legal encodings of
913
// any number. But the benefit of filling in those wasted ranges would not
914
// be worth the added complexity.)
915
private static String JavaDoc lengthPrefixBase64(long number) {
916         int length = 7;
917         for (int i = 0; i < 7; ++i) {
918             if (number < (1L << ((i * 6) + 3))) {
919                 length = i;
920                 break;
921             }
922         }
923         StringBuffer JavaDoc result = new StringBuffer JavaDoc(length + 1);
924         result.append(base64Character((length << 3) + (int) ((number >> (6 * length)) & 0x7)));
925         while (--length >= 0) {
926             result.append(base64Character((int) ((number >> (6 * length)) & 0x3f)));
927         }
928         return result.toString();
929     }
930
931     private static int charValue(char c) {
932         int index = BASE_64_ENCODING.indexOf(c);
933         // The "+ 1" is very intentional. For a blank (or anything else that
934
// is not a legal character), we want to return 0. For legal
935
// characters, we want to return one greater than their position, so
936
// that a blank is correctly distinguished from '-'.
937
return index + 1;
938     }
939
940     private static void appendEncodedCharacter(StringBuffer JavaDoc buffer, int c) {
941         while (c > 62) {
942             buffer.append('z');
943             c -= 63;
944         }
945         buffer.append(base64Character(c));
946     }
947
948     private static int getIntProperty(String JavaDoc property, int defaultValue) {
949         int result = defaultValue;
950         if (property != null) {
951             try {
952                 result = Integer.parseInt(property);
953                 if (result < 1) {
954                     // It has to be a positive integer. Use the default.
955
result = defaultValue;
956                 }
957             } catch (NumberFormatException JavaDoc e) {
958                 // Leave as default value
959
}
960         }
961         return result;
962     }
963
964     private String JavaDoc generateFeatureVersionSuffix(BuildTimeFeature buildFeature) throws CoreException {
965         if (!generateVersionSuffix || buildFeature.getContextQualifierLength() == -1) {
966             return null; // do nothing
967
}
968
969         Properties properties = getBuildProperties();
970         int significantDigits = getIntProperty((String JavaDoc) properties.get(PROPERTY_SIGNIFICANT_VERSION_DIGITS), -1);
971         if (significantDigits == -1)
972             significantDigits = getIntProperty(AbstractScriptGenerator.getImmutableAntProperty(PROPERTY_SIGNIFICANT_VERSION_DIGITS), Integer.MAX_VALUE);
973         int maxGeneratedLength = getIntProperty((String JavaDoc) properties.get(PROPERTY_GENERATED_VERSION_LENGTH), -1);
974         if (maxGeneratedLength == -1)
975             maxGeneratedLength = getIntProperty(AbstractScriptGenerator.getImmutableAntProperty(PROPERTY_GENERATED_VERSION_LENGTH), 28);
976
977         long majorSum = 0L;
978         long minorSum = 0L;
979         long serviceSum = 0L;
980
981         // Include the version of this algorithm as part of the suffix, so that
982
// we have a way to make sure all suffixes increase when the algorithm
983
// changes.
984
majorSum += QUALIFIER_SUFFIX_VERSION;
985
986         IIncludedFeatureReference[] referencedFeatures = buildFeature.getIncludedFeatureReferences();
987         IPluginEntry[] pluginList = buildFeature.getRawPluginEntries();
988         int numElements = pluginList.length + referencedFeatures.length;
989         if (numElements == 0) {
990             // Empty feature.
991
return null;
992         }
993         String JavaDoc[] qualifiers = new String JavaDoc[numElements];
994         int idx = -1;
995
996         // Loop through the included features, adding the version number parts
997
// to the running totals and storing the qualifier suffixes.
998
for (int i = 0; i < referencedFeatures.length; i++) {
999             BuildTimeFeature refFeature = (BuildTimeFeature) getSite(false).findFeature(referencedFeatures[i].getVersionedIdentifier().getIdentifier(), null, false);
1000            if (refFeature == null) {
1001                qualifiers[++idx] = ""; //$NON-NLS-1$
1002
continue;
1003            }
1004            PluginVersionIdentifier version = refFeature.getVersionedIdentifier().getVersion();
1005            majorSum += version.getMajorComponent();
1006            minorSum += version.getMinorComponent();
1007            serviceSum += version.getServiceComponent();
1008            int contextLength = refFeature.getContextQualifierLength();
1009            ++contextLength; //account for the '-' separating the context qualifier and suffix
1010
String JavaDoc qualifier = version.getQualifierComponent();
1011            // The entire qualifier of the nested feature is often too long to
1012
// include in the suffix computation for the containing feature,
1013
// and using it would result in extremely long qualifiers for
1014
// umbrella features. So instead we want to use just the suffix
1015
// part of the qualifier, or just the context part (if there is no
1016
// suffix part). See bug #162022.
1017
if (qualifier.length() > contextLength) {
1018                // Use the suffix part
1019
qualifiers[++idx] = qualifier.substring(contextLength);
1020            } else {
1021                // Use the context part
1022
qualifiers[++idx] = qualifier;
1023            }
1024        }
1025
1026        // Loop through the included plug-ins and fragments, adding the version
1027
// number parts to the running totals and storing the qualifiers.
1028

1029        for (int i = 0; i < pluginList.length; i++) {
1030            IPluginEntry entry = pluginList[i];
1031            VersionedIdentifier identifier = entry.getVersionedIdentifier();
1032            String JavaDoc versionRequested = identifier.getVersion().toString();
1033            BundleDescription model = getSite(false).getRegistry().getBundle(identifier.getIdentifier(), versionRequested, false);
1034            Version version = null;
1035            if (model != null) {
1036                version = model.getVersion();
1037            } else {
1038                if (versionRequested.endsWith(PROPERTY_QUALIFIER)) {
1039                    int resultingLength = versionRequested.length() - PROPERTY_QUALIFIER.length();
1040                    if (versionRequested.charAt(resultingLength - 1) == '.')
1041                        resultingLength--;
1042                    versionRequested = versionRequested.substring(0, resultingLength);
1043                }
1044                version = new Version(versionRequested);
1045            }
1046            
1047            majorSum += version.getMajor();
1048            minorSum += version.getMinor();
1049            serviceSum += version.getMicro();
1050            qualifiers[++idx] = version.getQualifier();
1051        }
1052
1053        // Limit the qualifiers to the specified number of significant digits,
1054
// and figure out what the longest qualifier is.
1055
int longestQualifier = 0;
1056        for (int i = 0; i < numElements; ++i) {
1057            if (qualifiers[i].length() > significantDigits) {
1058                qualifiers[i] = qualifiers[i].substring(0, significantDigits);
1059            }
1060            if (qualifiers[i].length() > longestQualifier) {
1061                longestQualifier = qualifiers[i].length();
1062            }
1063        }
1064
1065        StringBuffer JavaDoc result = new StringBuffer JavaDoc();
1066
1067        // Encode the sums of the first three parts of the version numbers.
1068
result.append(lengthPrefixBase64(majorSum));
1069        result.append(lengthPrefixBase64(minorSum));
1070        result.append(lengthPrefixBase64(serviceSum));
1071
1072        if (longestQualifier > 0) {
1073            // Calculate the sum at each position of the qualifiers.
1074
int[] qualifierSums = new int[longestQualifier];
1075            for (int i = 0; i < numElements; ++i) {
1076                for (int j = 0; j < qualifiers[i].length(); ++j) {
1077                    qualifierSums[j] += charValue(qualifiers[i].charAt(j));
1078                }
1079            }
1080            // Normalize the sums to be base 65.
1081
int carry = 0;
1082            for (int k = longestQualifier - 1; k >= 1; --k) {
1083                qualifierSums[k] += carry;
1084                carry = qualifierSums[k] / 65;
1085                qualifierSums[k] = qualifierSums[k] % 65;
1086            }
1087            qualifierSums[0] += carry;
1088            
1089            // Always use one character for overflow. This will be handled
1090
// correctly even when the overflow character itself overflows.
1091
result.append(lengthPrefixBase64(qualifierSums[0]));
1092            for (int m = 1; m < longestQualifier; ++m) {
1093                appendEncodedCharacter(result, qualifierSums[m]);
1094            }
1095        }
1096        // It is safe to strip any '-' characters from the end of the suffix.
1097
// (This won't happen very often, but it will save us a character or
1098
// two when it does.)
1099
while (result.length() > 0 && result.charAt(result.length() - 1) == '-') {
1100            result.deleteCharAt(result.length() - 1);
1101        }
1102
1103        // If the resulting suffix is too long, shorten it to the designed length.
1104
if (maxGeneratedLength > result.length()) {
1105            return result.toString();
1106        }
1107        return result.substring(0, maxGeneratedLength);
1108    }
1109
1110    /**
1111     * @param models
1112     * @throws CoreException
1113     */

1114    private void generateModels(List models) throws CoreException {
1115        if (scriptGeneration == false)
1116            return;
1117        if (binaryFeature == false || models.isEmpty())
1118            return;
1119
1120        Set generatedScripts = new HashSet(models.size());
1121        for (Iterator iterator = models.iterator(); iterator.hasNext();) {
1122            BundleDescription model = (BundleDescription) iterator.next();
1123            if (generatedScripts.contains(model))
1124                continue;
1125            generatedScripts.add(model);
1126
1127            //Get the corresponding plug-in entries (from a feature object) associated with the model
1128
//and generate the script if one the configuration is being built. The generated scripts
1129
//are configuration agnostic so we only generate once.
1130
Set matchingEntries = (Set) ((Properties) model.getUserObject()).get(PLUGIN_ENTRY);
1131            if (matchingEntries.isEmpty())
1132                return;
1133
1134            Iterator entryIter = matchingEntries.iterator();
1135            IPluginEntry correspondingEntry = (IPluginEntry) entryIter.next();
1136            List list = selectConfigs(correspondingEntry);
1137            if (list.size() == 0)
1138                continue;
1139
1140            ModelBuildScriptGenerator generator = new ModelBuildScriptGenerator();
1141            generator.setBuildSiteFactory(siteFactory);
1142            generator.setCompiledElements(getCompiledElements());
1143            generator.setIgnoreMissingPropertiesFile(isIgnoreMissingPropertiesFile());
1144            generator.setModel(model); // setModel has to be called before configurePersistentProperties because it reads the model's properties
1145
generator.setFeatureGenerator(this);
1146            generator.setPluginPath(getPluginPath());
1147            generator.setBuildingOSGi(isBuildingOSGi());
1148            generator.setDevEntries(devEntries);
1149            generator.includePlatformIndependent(isPlatformIndependentIncluded());
1150            generator.setSignJars(signJars);
1151            generator.setAssociatedEntry(correspondingEntry);
1152            generator.generate();
1153        }
1154
1155    }
1156
1157    /**
1158     * Set this object's feature id to be the given value.
1159     *
1160     * @param featureID the feature id
1161     * @throws CoreException if the given feature id is <code>null</code>
1162     */

1163    public void setFeature(String JavaDoc featureID) throws CoreException {
1164        if (featureID == null) {
1165            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, Messages.error_missingFeatureId, null));
1166        }
1167        this.featureIdentifier = featureID;
1168    }
1169
1170    public static String JavaDoc getNormalizedName(IFeature feature) {
1171        return feature.getVersionedIdentifier().toString();
1172    }
1173
1174    private void initializeVariables() throws CoreException {
1175        feature = getSite(false).findFeature(featureIdentifier, searchedVersion, true);
1176
1177        if (featureRootLocation == null) {
1178            featureRootLocation = feature.getURL().getPath();
1179            int i = featureRootLocation.lastIndexOf(Constants.FEATURE_FILENAME_DESCRIPTOR);
1180            if (i != -1)
1181                featureRootLocation = featureRootLocation.substring(0, i);
1182        }
1183        initializeFeatureNames();
1184
1185        if (feature instanceof BuildTimeFeature) {
1186            if (getBuildProperties() == MissingProperties.getInstance() || AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE)) {
1187                BuildTimeFeature buildFeature = (BuildTimeFeature) feature;
1188                scriptGeneration = false;
1189                buildFeature.setBinary(true);
1190            }
1191        }
1192
1193        Properties properties = getBuildProperties();
1194        customFeatureCallbacks = properties.getProperty(PROPERTY_CUSTOM_BUILD_CALLBACKS);
1195        if (TRUE.equalsIgnoreCase(customFeatureCallbacks))
1196            customFeatureCallbacks = DEFAULT_CUSTOM_BUILD_CALLBACKS_FILE;
1197        else if (FALSE.equalsIgnoreCase(customFeatureCallbacks))
1198            customFeatureCallbacks = null;
1199        customCallbacksBuildpath = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_BUILDPATH, "."); //$NON-NLS-1$
1200
customCallbacksFailOnError = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_FAILONERROR, FALSE);
1201        customCallbacksInheritAll = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_INHERITALL);
1202    }
1203
1204    private void initializeFeatureNames() throws CoreException {
1205        featureFullName = getNormalizedName(feature);
1206        featureFolderName = DEFAULT_FEATURE_LOCATION + '/' + featureFullName;
1207        sourceFeatureFullName = computeSourceFeatureName(feature, false);
1208        sourceFeatureFullNameVersionned = computeSourceFeatureName(feature, true);
1209        featureTempFolder = Utils.getPropertyFormat(PROPERTY_FEATURE_TEMP_FOLDER);
1210    }
1211
1212    public void setSourceFeatureId(String JavaDoc id) {
1213        sourceFeatureFullName = id;
1214    }
1215
1216    private String JavaDoc computeSourceFeatureName(IFeature featureForName, boolean withNumber) throws CoreException {
1217        String JavaDoc sourceFeatureName = getBuildProperties().getProperty(PROPERTY_SOURCE_FEATURE_NAME);
1218        if (sourceFeatureName == null)
1219            sourceFeatureName = sourceFeatureFullName;
1220        if (sourceFeatureName == null)
1221            sourceFeatureName = featureForName.getVersionedIdentifier().getIdentifier() + ".source"; //$NON-NLS-1$
1222
return sourceFeatureName + (withNumber ? "_" + featureForName.getVersionedIdentifier().getVersion().toString() : ""); //$NON-NLS-1$ //$NON-NLS-2$
1223
}
1224
1225    /**
1226     * Return a properties object constructed from the build.properties file
1227     * for the given feature. If no file exists, then an empty properties
1228     * object is returned.
1229     *
1230     * @return Properties the feature's build.properties
1231     * @throws CoreException
1232     * @see Feature
1233     */

1234    protected Properties getBuildProperties() throws CoreException {
1235        if (buildProperties == null)
1236            buildProperties = readProperties(featureRootLocation, PROPERTIES_FILE, isIgnoreMissingPropertiesFile() ? IStatus.OK : IStatus.WARNING);
1237        return buildProperties;
1238    }
1239
1240    /**
1241     * Add the <code>children</code> target to the given Ant script.
1242     * Delegates some target call to all-template only if the property
1243     * includeChildren is set.
1244     */

1245    private void generateChildrenTarget() {
1246        script.println();
1247        script.printTargetDeclaration(TARGET_CHILDREN, null, PROPERTY_INCLUDE_CHILDREN, null, null);
1248        script.printAntCallTask(TARGET_ALL_CHILDREN, true, null);
1249        script.printTargetEnd();
1250    }
1251
1252    /**
1253     * Add the <code>build.jars</code> target to the given Ant script.
1254     */

1255    private void generateBuildJarsTarget() {
1256        script.println();
1257        script.printTargetDeclaration(TARGET_BUILD_JARS, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_buildJars, featureIdentifier));
1258        Map params = new HashMap(1);
1259        params.put(PROPERTY_TARGET, TARGET_BUILD_JARS);
1260        script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
1261        script.printTargetEnd();
1262        script.println();
1263        script.printTargetDeclaration(TARGET_BUILD_SOURCES, TARGET_INIT, null, null, null);
1264        params.clear();
1265        params.put(PROPERTY_TARGET, TARGET_BUILD_SOURCES);
1266        script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
1267        script.printTargetEnd();
1268    }
1269
1270    /**
1271     * Add the <code>refresh</code> target to the given Ant script.
1272     */

1273    private void generateRefreshTarget() {
1274        script.println();
1275        script.printTargetDeclaration(TARGET_REFRESH, TARGET_INIT, PROPERTY_ECLIPSE_RUNNING, null, NLS.bind(Messages.build_feature_refresh, featureIdentifier));
1276        script.printConvertPathTask(new Path(featureRootLocation).removeLastSegments(0).toOSString().replace('\\', '/'), PROPERTY_RESOURCE_PATH, false);
1277        script.printRefreshLocalTask(Utils.getPropertyFormat(PROPERTY_RESOURCE_PATH), "infinite"); //$NON-NLS-1$
1278
Map params = new HashMap(2);
1279        params.put(PROPERTY_TARGET, TARGET_REFRESH);
1280        script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
1281        script.printTargetEnd();
1282    }
1283
1284    public void setGenerateIncludedFeatures(boolean recursiveGeneration) {
1285        analyseIncludedFeatures = recursiveGeneration;
1286    }
1287
1288    protected void collectElementToAssemble(IFeature featureToCollect) throws CoreException {
1289        if (assemblyData == null)
1290            return;
1291
1292        /* collect binary features */
1293        if (featureToCollect instanceof BuildTimeFeature && ((BuildTimeFeature) featureToCollect).isBinary()) {
1294            basicCollectElementToAssemble(featureToCollect);
1295            return;
1296        }
1297
1298        // don't collect if bin.includes is empty, or we are generating source;
1299
if (getBuildProperties().get(PROPERTY_BIN_INCLUDES) == null || sourceFeatureGeneration)
1300            return;
1301
1302        basicCollectElementToAssemble(featureToCollect);
1303    }
1304
1305    private void basicCollectElementToAssemble(IFeature featureToCollect) {
1306        if (assemblyData == null)
1307            return;
1308        List correctConfigs = selectConfigs(featureToCollect);
1309        // Here, we could sort if the feature is a common one or not by
1310
// comparing the size of correctConfigs
1311
for (Iterator iter = correctConfigs.iterator(); iter.hasNext();) {
1312            Config config = (Config) iter.next();
1313            assemblyData.addFeature(config, feature);
1314        }
1315    }
1316
1317    /**
1318     * Method generateSourceFeature.
1319     */

1320    private void generateSourceFeature() throws CoreException {
1321        Feature featureExample = (Feature) feature;
1322        sourceFeature = createSourceFeature(featureExample);
1323        associateExtraPluginsAndFeatures();
1324        if (isBuildingOSGi())
1325            sourcePlugin = create30SourcePlugin();
1326        else
1327            sourcePlugin = createSourcePlugin();
1328
1329        generateSourceFragment();
1330    }
1331
1332    private void generateSourceFragment() throws CoreException {
1333        Map fragments = sourceToGather.getElementEntries();
1334        for (Iterator iter = fragments.entrySet().iterator(); iter.hasNext();) {
1335            Map.Entry fragmentInfo = (Map.Entry) iter.next();
1336            Config configInfo = (Config) fragmentInfo.getKey();
1337            if (configInfo.equals(Config.genericConfig()))
1338                continue;
1339            PluginEntry sourceFragment = new PluginEntry();
1340            String JavaDoc sourceFragmentId = sourceFeature.getFeatureIdentifier() + "." + configInfo.toString("."); //$NON-NLS-1$ //$NON-NLS-2$
1341
sourceFragment.setPluginIdentifier(sourceFragmentId);
1342            sourceFragment.setPluginVersion(sourceFeature.getFeatureVersion());
1343            sourceFragment.setOS(configInfo.getOs());
1344            sourceFragment.setWS(configInfo.getWs());
1345            sourceFragment.setArch(configInfo.getArch());
1346            sourceFragment.isFragment(true);
1347            //sourceFeature.addPluginEntryModel(sourceFragment);
1348
if (isBuildingOSGi())
1349                create30SourceFragment(sourceFragment, sourcePlugin);
1350            else
1351                createSourceFragment(sourceFragment, sourcePlugin);
1352        }
1353    }
1354
1355    //Add the relevant source fragments to the source feature
1356
private void addSourceFragmentsToFeature() {
1357        Map fragments = sourceToGather.getElementEntries();
1358        for (Iterator iter = fragments.entrySet().iterator(); iter.hasNext();) {
1359            Map.Entry fragmentInfo = (Map.Entry) iter.next();
1360            Config configInfo = (Config) fragmentInfo.getKey();
1361            if (configInfo.equals(Config.genericConfig()))
1362                continue;
1363            Set sourceList = (Set) fragmentInfo.getValue();
1364            if (sourceList.size() == 0)
1365                continue;
1366            PluginEntry sourceFragment = new PluginEntry();
1367            String JavaDoc sourceFragmentId = sourceFeature.getFeatureIdentifier() + "." + configInfo.toString("."); //$NON-NLS-1$ //$NON-NLS-2$
1368
sourceFragment.setPluginIdentifier(sourceFragmentId);
1369            sourceFragment.setPluginVersion(sourceFeature.getFeatureVersion());
1370            sourceFragment.setOS(configInfo.getOs());
1371            sourceFragment.setWS(configInfo.getWs());
1372            sourceFragment.setArch(configInfo.getArch());
1373            sourceFragment.isFragment(true);
1374            sourceFeature.addPluginEntryModel(sourceFragment);
1375            //createSourceFragment(sourceFragment, sourcePlugin);
1376
}
1377    }
1378
1379    private void generateSourceFeatureScripts() throws CoreException {
1380        FeatureBuildScriptGenerator sourceScriptGenerator = new FeatureBuildScriptGenerator(sourceFeatureFullName, sourceFeature.getFeatureVersion(), assemblyData);
1381        sourceScriptGenerator.setGenerateIncludedFeatures(true);
1382        sourceScriptGenerator.setAnalyseChildren(true);
1383        sourceScriptGenerator.setSourceToGather(sourceToGather);
1384        sourceScriptGenerator.setBinaryFeatureGeneration(true);
1385        sourceScriptGenerator.setSourceFeatureGeneration(false);
1386        sourceScriptGenerator.setScriptGeneration(true);
1387        sourceScriptGenerator.setPluginPath(pluginPath);
1388        sourceScriptGenerator.setBuildSiteFactory(siteFactory);
1389        sourceScriptGenerator.setDevEntries(devEntries);
1390        sourceScriptGenerator.setCompiledElements(getCompiledElements());
1391        sourceScriptGenerator.setSourcePluginOnly(sourcePluginOnly);
1392        sourceScriptGenerator.setBuildingOSGi(isBuildingOSGi());
1393        sourceScriptGenerator.includePlatformIndependent(isPlatformIndependentIncluded());
1394        sourceScriptGenerator.setIgnoreMissingPropertiesFile(isIgnoreMissingPropertiesFile());
1395        sourceScriptGenerator.setGenerateVersionSuffix(generateVersionSuffix);
1396        sourceScriptGenerator.generate();
1397    }
1398
1399    // Add extra plugins into the given feature.
1400
private void associateExtraPluginsAndFeatures() throws CoreException {
1401        for (int i = 1; i < extraPlugins.length; i++) {
1402            BundleDescription model;
1403            // see if we have a plug-in or a fragment
1404
if (extraPlugins[i].startsWith("feature@")) { //$NON-NLS-1$
1405
String JavaDoc id = extraPlugins[i].substring(8);
1406                IncludedFeatureReference include = new IncludedFeatureReference();
1407                include.setFeatureIdentifier(id);
1408                include.setFeatureVersion(GENERIC_VERSION_NUMBER);
1409                sourceFeature.addIncludedFeatureReferenceModel(include);
1410            } else {
1411                Object JavaDoc[] items = Utils.parseExtraBundlesString(extraPlugins[i], true);
1412                model = getSite(false).getRegistry().getResolvedBundle((String JavaDoc) items[0], ((Version) items[1]).toString());
1413                if (model == null) {
1414                    String JavaDoc message = NLS.bind(Messages.exception_missingPlugin, extraPlugins[i]);
1415                    BundleHelper.getDefault().getLog().log(new Status(IStatus.WARNING, extraPlugins[i], EXCEPTION_PLUGIN_MISSING, message, null));
1416                    continue;
1417                }
1418                PluginEntry entry = new PluginEntry();
1419                entry.setPluginIdentifier(model.getSymbolicName());
1420                entry.setPluginVersion(model.getVersion().toString());
1421                entry.setUnpack(((Boolean JavaDoc) items[2]).booleanValue());
1422                sourceFeature.addPluginEntryModel(entry);
1423            }
1424        }
1425    }
1426
1427    private PluginEntry create30SourcePlugin() throws CoreException {
1428        //Create an object representing the plugin
1429
PluginEntry result = new PluginEntry();
1430        String JavaDoc sourcePluginId = sourceFeature.getFeatureIdentifier();
1431        result.setPluginIdentifier(sourcePluginId);
1432        result.setPluginVersion(sourceFeature.getFeatureVersion());
1433        sourceFeature.addPluginEntryModel(result);
1434        // create the directory for the plugin
1435
IPath sourcePluginDirURL = new Path(workingDirectory + '/' + DEFAULT_PLUGIN_LOCATION + '/' + getSourcePluginName(result, false));
1436        File sourcePluginDir = sourcePluginDirURL.toFile();
1437        new File(sourcePluginDir, "META-INF").mkdirs(); //$NON-NLS-1$
1438

1439        // Create the MANIFEST.MF
1440
StringBuffer JavaDoc buffer;
1441        Path templateManifest = new Path(TEMPLATE + "/30/plugin/" + Constants.BUNDLE_FILENAME_DESCRIPTOR); //$NON-NLS-1$
1442
URL JavaDoc templateManifestURL = BundleHelper.getDefault().find(templateManifest);
1443        if (templateManifestURL == null) {
1444            IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_READING_FILE, NLS.bind(Messages.error_readingDirectory, templateManifest), null);
1445            BundleHelper.getDefault().getLog().log(status);
1446            return null;
1447        }
1448        try {
1449            buffer = readFile(templateManifestURL.openStream());
1450        } catch (IOException e1) {
1451            String JavaDoc message = NLS.bind(Messages.exception_readingFile, templateManifestURL.toExternalForm());
1452            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e1));
1453        }
1454        int beginId = scan(buffer, 0, REPLACED_PLUGIN_ID);
1455        buffer.replace(beginId, beginId + REPLACED_PLUGIN_ID.length(), result.getPluginIdentifier());
1456        //set the version number
1457
beginId = scan(buffer, beginId, REPLACED_PLUGIN_VERSION);
1458        buffer.replace(beginId, beginId + REPLACED_PLUGIN_VERSION.length(), result.getPluginVersion());
1459        try {
1460            Utils.transferStreams(new ByteArrayInputStream(buffer.toString().getBytes()), new FileOutputStream(sourcePluginDirURL.append(Constants.BUNDLE_FILENAME_DESCRIPTOR).toOSString()));
1461        } catch (IOException e1) {
1462            String JavaDoc message = NLS.bind(Messages.exception_writingFile, templateManifestURL.toExternalForm());
1463            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e1));
1464        }
1465
1466        //Copy the plugin.xml
1467
try {
1468            InputStream pluginXML = BundleHelper.getDefault().getBundle().getEntry(TEMPLATE + "/30/plugin/plugin.xml").openStream(); //$NON-NLS-1$
1469
Utils.transferStreams(pluginXML, new FileOutputStream(sourcePluginDirURL.append(Constants.PLUGIN_FILENAME_DESCRIPTOR).toOSString()));
1470        } catch (IOException e1) {
1471            String JavaDoc message = NLS.bind(Messages.exception_readingFile, TEMPLATE + "/30/plugin/plugin.xml"); //$NON-NLS-1$
1472
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e1));
1473        }
1474
1475        //Copy the other files
1476
Collection copiedFiles = Utils.copyFiles(featureRootLocation + '/' + "sourceTemplatePlugin", sourcePluginDir.getAbsolutePath()); //$NON-NLS-1$
1477
if (copiedFiles.contains(Constants.BUNDLE_FILENAME_DESCRIPTOR)) {
1478            //make sure the manifest.mf has the version we want
1479
replaceManifestValue(sourcePluginDirURL.append(Constants.BUNDLE_FILENAME_DESCRIPTOR).toOSString(), org.osgi.framework.Constants.BUNDLE_VERSION, result.getPluginVersion()); //$NON-NLS-1$
1480
}
1481
1482        // If a build.properties file already exist then we use it supposing it is correct.
1483
File buildProperty = sourcePluginDirURL.append(PROPERTIES_FILE).toFile();
1484        if (!buildProperty.exists()) {
1485            copiedFiles.add(Constants.PLUGIN_FILENAME_DESCRIPTOR); //Because the plugin.xml is not copied, we need to add it to the file
1486
copiedFiles.add("src/**/*.zip"); //$NON-NLS-1$
1487
copiedFiles.add(Constants.BUNDLE_FILENAME_DESCRIPTOR);//Because the manifest.mf is not copied, we need to add it to the file
1488
Properties sourceBuildProperties = new Properties();
1489            sourceBuildProperties.put(PROPERTY_BIN_INCLUDES, Utils.getStringFromCollection(copiedFiles, ",")); //$NON-NLS-1$
1490
sourceBuildProperties.put(SOURCE_PLUGIN_ATTRIBUTE, "true"); //$NON-NLS-1$
1491
try {
1492                OutputStream buildFile = new BufferedOutputStream(new FileOutputStream(buildProperty));
1493                try {
1494                    sourceBuildProperties.store(buildFile, null);
1495                } finally {
1496                    buildFile.close();
1497                }
1498            } catch (FileNotFoundException e) {
1499                String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1500                throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1501            } catch (IOException e) {
1502                String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1503                throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1504            }
1505        }
1506
1507        PDEState state = getSite(false).getRegistry();
1508        BundleDescription oldBundle = state.getResolvedBundle(result.getPluginIdentifier());
1509        if (oldBundle != null)
1510            state.getState().removeBundle(oldBundle);
1511        state.addBundle(sourcePluginDir);
1512
1513        return result;
1514    }
1515
1516    /**
1517     * Method createSourcePlugin.
1518     */

1519    private PluginEntry createSourcePlugin() throws CoreException {
1520        //Create an object representing the plugin
1521
PluginEntry result = new PluginEntry();
1522        String JavaDoc sourcePluginId = sourceFeature.getFeatureIdentifier();
1523        result.setPluginIdentifier(sourcePluginId);
1524        result.setPluginVersion(sourceFeature.getFeatureVersion());
1525        sourceFeature.addPluginEntryModel(result);
1526        // create the directory for the plugin
1527
IPath sourcePluginDirURL = new Path(workingDirectory + '/' + DEFAULT_PLUGIN_LOCATION + '/' + getSourcePluginName(result, false));
1528        File sourcePluginDir = sourcePluginDirURL.toFile();
1529        sourcePluginDir.mkdirs();
1530
1531        // Create the plugin.xml
1532
StringBuffer JavaDoc buffer;
1533        Path templatePluginXML = new Path(TEMPLATE + "/21/plugin/" + Constants.PLUGIN_FILENAME_DESCRIPTOR); //$NON-NLS-1$
1534
URL JavaDoc templatePluginURL = BundleHelper.getDefault().find(templatePluginXML);
1535        if (templatePluginURL == null) {
1536            IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_READING_FILE, NLS.bind(Messages.error_readingDirectory, templatePluginXML), null);
1537            BundleHelper.getDefault().getLog().log(status);
1538            return null;
1539        }
1540        try {
1541            buffer = readFile(templatePluginURL.openStream());
1542        } catch (IOException e1) {
1543            String JavaDoc message = NLS.bind(Messages.exception_readingFile, templatePluginURL.toExternalForm());
1544            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e1));
1545        }
1546        int beginId = scan(buffer, 0, REPLACED_PLUGIN_ID);
1547        buffer.replace(beginId, beginId + REPLACED_PLUGIN_ID.length(), result.getPluginIdentifier());
1548        //set the version number
1549
beginId = scan(buffer, beginId, REPLACED_PLUGIN_VERSION);
1550        buffer.replace(beginId, beginId + REPLACED_PLUGIN_VERSION.length(), result.getPluginVersion());
1551        try {
1552            Utils.transferStreams(new ByteArrayInputStream(buffer.toString().getBytes()), new FileOutputStream(sourcePluginDirURL.append(Constants.PLUGIN_FILENAME_DESCRIPTOR).toOSString()));
1553        } catch (IOException e1) {
1554            String JavaDoc message = NLS.bind(Messages.exception_writingFile, templatePluginURL.toExternalForm());
1555            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e1));
1556        }
1557        Collection copiedFiles = Utils.copyFiles(featureRootLocation + '/' + "sourceTemplatePlugin", sourcePluginDir.getAbsolutePath()); //$NON-NLS-1$
1558
if (copiedFiles.contains(Constants.PLUGIN_FILENAME_DESCRIPTOR)) {
1559            replaceXMLAttribute(sourcePluginDirURL.append(Constants.PLUGIN_FILENAME_DESCRIPTOR).toOSString(), PLUGIN_START_TAG, VERSION, result.getPluginVersion());
1560        }
1561        // If a build.properties file already exist then we use it supposing it is correct.
1562
File buildProperty = sourcePluginDirURL.append(PROPERTIES_FILE).toFile();
1563        if (!buildProperty.exists()) {
1564            copiedFiles.add(Constants.PLUGIN_FILENAME_DESCRIPTOR); //Because the plugin.xml is not copied, we need to add it to the file
1565
copiedFiles.add("src/**/*.zip"); //$NON-NLS-1$
1566
Properties sourceBuildProperties = new Properties();
1567            sourceBuildProperties.put(PROPERTY_BIN_INCLUDES, Utils.getStringFromCollection(copiedFiles, ",")); //$NON-NLS-1$
1568
sourceBuildProperties.put(SOURCE_PLUGIN_ATTRIBUTE, "true"); //$NON-NLS-1$
1569
try {
1570                OutputStream buildFile = new BufferedOutputStream(new FileOutputStream(buildProperty));
1571                try {
1572                    sourceBuildProperties.store(buildFile, null);
1573                } finally {
1574                    buildFile.close();
1575                }
1576            } catch (FileNotFoundException e) {
1577                String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1578                throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1579            } catch (IOException e) {
1580                String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1581                throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1582            }
1583        }
1584        PDEState state = getSite(false).getRegistry();
1585        BundleDescription oldBundle = state.getResolvedBundle(result.getPluginIdentifier());
1586        if (oldBundle != null)
1587            state.getState().removeBundle(oldBundle);
1588        state.addBundle(sourcePluginDir);
1589        return result;
1590    }
1591
1592    private void create30SourceFragment(PluginEntry fragment, PluginEntry plugin) throws CoreException {
1593        // create the directory for the plugin
1594
Path sourceFragmentDirURL = new Path(workingDirectory + '/' + DEFAULT_PLUGIN_LOCATION + '/' + getSourcePluginName(fragment, false));
1595        File sourceFragmentDir = new File(sourceFragmentDirURL.toOSString());
1596        new File(sourceFragmentDir, "META-INF").mkdirs(); //$NON-NLS-1$
1597
try {
1598            // read the content of the template file
1599
Path fragmentPath = new Path(TEMPLATE + "/30/fragment/" + Constants.BUNDLE_FILENAME_DESCRIPTOR);//$NON-NLS-1$
1600
URL JavaDoc templateLocation = BundleHelper.getDefault().find(fragmentPath);
1601            if (templateLocation == null) {
1602                IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_READING_FILE, NLS.bind(Messages.error_readingDirectory, fragmentPath), null);
1603                BundleHelper.getDefault().getLog().log(status);
1604                return;
1605            }
1606
1607            //Copy the fragment.xml
1608
try {
1609                InputStream fragmentXML = BundleHelper.getDefault().getBundle().getEntry(TEMPLATE + "/30/fragment/fragment.xml").openStream(); //$NON-NLS-1$
1610
Utils.transferStreams(fragmentXML, new FileOutputStream(sourceFragmentDirURL.append(Constants.FRAGMENT_FILENAME_DESCRIPTOR).toOSString()));
1611            } catch (IOException e1) {
1612                String JavaDoc message = NLS.bind(Messages.exception_readingFile, TEMPLATE + "/30/fragment/fragment.xml"); //$NON-NLS-1$
1613
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e1));
1614            }
1615
1616            StringBuffer JavaDoc buffer = readFile(templateLocation.openStream());
1617            //Set the Id of the fragment
1618
int beginId = scan(buffer, 0, REPLACED_FRAGMENT_ID);
1619            buffer.replace(beginId, beginId + REPLACED_FRAGMENT_ID.length(), fragment.getPluginIdentifier());
1620            // set the version number
1621
beginId = scan(buffer, beginId, REPLACED_FRAGMENT_VERSION);
1622            buffer.replace(beginId, beginId + REPLACED_FRAGMENT_VERSION.length(), fragment.getPluginVersion());
1623            // Set the Id of the plugin for the fragment
1624
beginId = scan(buffer, beginId, REPLACED_PLUGIN_ID);
1625            buffer.replace(beginId, beginId + REPLACED_PLUGIN_ID.length(), plugin.getPluginIdentifier());
1626            // set the version number of the plugin to which the fragment is attached to
1627
BundleDescription effectivePlugin = getSite(false).getRegistry().getResolvedBundle(plugin.getVersionedIdentifier().getIdentifier(), plugin.getPluginVersion());
1628            beginId = scan(buffer, beginId, REPLACED_PLUGIN_VERSION);
1629            buffer.replace(beginId, beginId + REPLACED_PLUGIN_VERSION.length(), effectivePlugin.getVersion().toString());
1630            // Set the platform filter of the fragment
1631
beginId = scan(buffer, beginId, REPLACED_PLATFORM_FILTER);
1632            buffer.replace(beginId, beginId + REPLACED_PLATFORM_FILTER.length(), "(& (osgi.ws=" + fragment.getWS() + ") (osgi.os=" + fragment.getOS() + ") (osgi.arch=" + fragment.getOSArch() + "))");
1633            
1634            Utils.transferStreams(new ByteArrayInputStream(buffer.toString().getBytes()), new FileOutputStream(sourceFragmentDirURL.append(Constants.BUNDLE_FILENAME_DESCRIPTOR).toOSString()));
1635            Collection copiedFiles = Utils.copyFiles(featureRootLocation + '/' + "sourceTemplateFragment", sourceFragmentDir.getAbsolutePath()); //$NON-NLS-1$
1636
if (copiedFiles.contains(Constants.BUNDLE_FILENAME_DESCRIPTOR)) {
1637                //make sure the manifest.mf has the versions we want
1638
replaceManifestValue(sourceFragmentDirURL.append(Constants.BUNDLE_FILENAME_DESCRIPTOR).toOSString(), org.osgi.framework.Constants.BUNDLE_VERSION, fragment.getPluginVersion());
1639                String JavaDoc host = plugin.getPluginIdentifier() + ';' + org.osgi.framework.Constants.BUNDLE_VERSION + '=' + effectivePlugin.getVersion().toString();
1640                replaceManifestValue(sourceFragmentDirURL.append(Constants.BUNDLE_FILENAME_DESCRIPTOR).toOSString(), org.osgi.framework.Constants.FRAGMENT_HOST, host);
1641            }
1642            File buildProperty = sourceFragmentDirURL.append(PROPERTIES_FILE).toFile();
1643            if (!buildProperty.exists()) { //If a build.properties file already exist then we don't override it.
1644
copiedFiles.add(Constants.FRAGMENT_FILENAME_DESCRIPTOR); //Because the fragment.xml is not copied, we need to add it to the file
1645
copiedFiles.add("src/**"); //$NON-NLS-1$
1646
copiedFiles.add(Constants.BUNDLE_FILENAME_DESCRIPTOR);
1647                Properties sourceBuildProperties = new Properties();
1648                sourceBuildProperties.put(PROPERTY_BIN_INCLUDES, Utils.getStringFromCollection(copiedFiles, ",")); //$NON-NLS-1$
1649
sourceBuildProperties.put("sourcePlugin", "true"); //$NON-NLS-1$ //$NON-NLS-2$
1650
try {
1651                    OutputStream buildFile = new BufferedOutputStream(new FileOutputStream(buildProperty));
1652                    try {
1653                        sourceBuildProperties.store(buildFile, null);
1654                    } finally {
1655                        buildFile.close();
1656                    }
1657                } catch (FileNotFoundException e) {
1658                    String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1659                    throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1660                } catch (IOException e) {
1661                    String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1662                    throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1663                }
1664            }
1665        } catch (IOException e) {
1666            String JavaDoc message = NLS.bind(Messages.exception_writingFile, sourceFragmentDir.getName());
1667            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, null));
1668        }
1669        PDEState state = getSite(false).getRegistry();
1670        BundleDescription oldBundle = state.getResolvedBundle(fragment.getPluginIdentifier());
1671        if (oldBundle != null)
1672            state.getState().removeBundle(oldBundle);
1673        state.addBundle(sourceFragmentDir);
1674    }
1675
1676    private void createSourceFragment(PluginEntry fragment, PluginEntry plugin) throws CoreException {
1677        // create the directory for the plugin
1678
Path sourceFragmentDirURL = new Path(workingDirectory + '/' + DEFAULT_PLUGIN_LOCATION + '/' + getSourcePluginName(fragment, false));
1679        File sourceFragmentDir = new File(sourceFragmentDirURL.toOSString());
1680        sourceFragmentDir.mkdirs();
1681        try {
1682            // read the content of the template file
1683
Path fragmentPath = new Path(TEMPLATE + "/21/fragment/" + Constants.FRAGMENT_FILENAME_DESCRIPTOR);//$NON-NLS-1$
1684
URL JavaDoc templateLocation = BundleHelper.getDefault().find(fragmentPath);
1685            if (templateLocation == null) {
1686                IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_READING_FILE, NLS.bind(Messages.error_readingDirectory, fragmentPath), null);
1687                BundleHelper.getDefault().getLog().log(status);
1688                return;
1689            }
1690
1691            StringBuffer JavaDoc buffer = readFile(templateLocation.openStream());
1692            //Set the Id of the fragment
1693
int beginId = scan(buffer, 0, REPLACED_FRAGMENT_ID);
1694            buffer.replace(beginId, beginId + REPLACED_FRAGMENT_ID.length(), fragment.getPluginIdentifier());
1695            // set the version number
1696
beginId = scan(buffer, beginId, REPLACED_FRAGMENT_VERSION);
1697            buffer.replace(beginId, beginId + REPLACED_FRAGMENT_VERSION.length(), fragment.getPluginVersion());
1698            // Set the Id of the plugin for the fragment
1699
beginId = scan(buffer, beginId, REPLACED_PLUGIN_ID);
1700            buffer.replace(beginId, beginId + REPLACED_PLUGIN_ID.length(), plugin.getPluginIdentifier());
1701            // set the version number of the plugin to which the fragment is attached to
1702
beginId = scan(buffer, beginId, REPLACED_PLUGIN_VERSION);
1703            buffer.replace(beginId, beginId + REPLACED_PLUGIN_VERSION.length(), plugin.getPluginVersion());
1704            Utils.transferStreams(new ByteArrayInputStream(buffer.toString().getBytes()), new FileOutputStream(sourceFragmentDirURL.append(Constants.FRAGMENT_FILENAME_DESCRIPTOR).toOSString()));
1705            Collection copiedFiles = Utils.copyFiles(featureRootLocation + '/' + "sourceTemplateFragment", sourceFragmentDir.getAbsolutePath()); //$NON-NLS-1$
1706
if (copiedFiles.contains(Constants.FRAGMENT_FILENAME_DESCRIPTOR)) {
1707                replaceXMLAttribute(sourceFragmentDirURL.append(Constants.FRAGMENT_FILENAME_DESCRIPTOR).toOSString(), FRAGMENT_START_TAG, VERSION, fragment.getPluginVersion());
1708                replaceXMLAttribute(sourceFragmentDirURL.append(Constants.FRAGMENT_FILENAME_DESCRIPTOR).toOSString(), FRAGMENT_START_TAG, PLUGIN_VERSION, plugin.getPluginVersion());
1709            }
1710            File buildProperty = sourceFragmentDirURL.append(PROPERTIES_FILE).toFile();
1711            if (!buildProperty.exists()) { //If a build.properties file already exist then we don't override it.
1712
copiedFiles.add(Constants.FRAGMENT_FILENAME_DESCRIPTOR); //Because the fragment.xml is not copied, we need to add it to the file
1713
copiedFiles.add("src/**"); //$NON-NLS-1$
1714
Properties sourceBuildProperties = new Properties();
1715                sourceBuildProperties.put(PROPERTY_BIN_INCLUDES, Utils.getStringFromCollection(copiedFiles, ",")); //$NON-NLS-1$
1716
sourceBuildProperties.put("sourcePlugin", "true"); //$NON-NLS-1$ //$NON-NLS-2$
1717
try {
1718                    OutputStream buildFile = new BufferedOutputStream(new FileOutputStream(buildProperty));
1719                    try {
1720                        sourceBuildProperties.store(buildFile, null);
1721                    } finally {
1722                        buildFile.close();
1723                    }
1724                } catch (FileNotFoundException e) {
1725                    String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1726                    throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1727                } catch (IOException e) {
1728                    String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1729                    throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1730                }
1731            }
1732        } catch (IOException e) {
1733            String JavaDoc message = NLS.bind(Messages.exception_writingFile, sourceFragmentDir.getName());
1734            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, null));
1735        }
1736        PDEState state = getSite(false).getRegistry();
1737        BundleDescription oldBundle = state.getResolvedBundle(fragment.getPluginIdentifier());
1738        if (oldBundle != null)
1739            state.getState().removeBundle(oldBundle);
1740        state.addBundle(sourceFragmentDir);
1741    }
1742
1743    public String JavaDoc getSourcePluginName(PluginEntry plugin, boolean versionSuffix) {
1744        return plugin.getPluginIdentifier() + (versionSuffix ? "_" + plugin.getPluginVersion() : ""); //$NON-NLS-1$ //$NON-NLS-2$
1745
}
1746
1747    public void setFeatureRootLocation(String JavaDoc featureLocation) {
1748        this.featureRootLocation = featureLocation;
1749    }
1750
1751    /**
1752     * Method setSourceToGather.
1753     *
1754     * @param sourceToGather
1755     */

1756    public void setSourceToGather(SourceFeatureInformation sourceToGather) {
1757        this.sourceToGather = sourceToGather;
1758    }
1759
1760    /**
1761     * Sets the sourceFeatureGeneration.
1762     *
1763     * @param sourceFeatureGeneration
1764     * The sourceFeatureGeneration to set
1765     */

1766    public void setSourceFeatureGeneration(boolean sourceFeatureGeneration) {
1767        this.sourceFeatureGeneration = sourceFeatureGeneration;
1768    }
1769
1770    /**
1771     * Sets the binaryFeatureGeneration.
1772     *
1773     * @param binaryFeatureGeneration
1774     * The binaryFeatureGeneration to set
1775     */

1776    public void setBinaryFeatureGeneration(boolean binaryFeatureGeneration) {
1777        this.binaryFeature = binaryFeatureGeneration;
1778    }
1779
1780    /**
1781     * Sets the scriptGeneration.
1782     *
1783     * @param scriptGeneration
1784     * The scriptGeneration to set
1785     */

1786    public void setScriptGeneration(boolean scriptGeneration) {
1787        this.scriptGeneration = scriptGeneration;
1788    }
1789
1790    /**
1791     * Returns the sourceFeatureGeneration.
1792     *
1793     * @return boolean
1794     */

1795    public boolean isSourceFeatureGeneration() {
1796        return sourceFeatureGeneration;
1797    }
1798
1799    /**
1800     * Sets whether or not to generate JNLP manifests
1801     *
1802     * @param value whether or not to generate JNLP manifests
1803     */

1804    public void setGenerateJnlp(boolean value) {
1805        generateJnlp = value;
1806    }
1807
1808    /**
1809     * Sets whether or not to sign any constructed jars.
1810     *
1811     * @param value whether or not to sign any constructed JARs
1812     */

1813    public void setSignJars(boolean value) {
1814        signJars = value;
1815    }
1816
1817    /**
1818     * Sets whether or not to generate the feature version suffix
1819     *
1820     * @param value whether or not to generate the feature version suffix
1821     */

1822    public void setGenerateVersionSuffix(boolean value) {
1823        generateVersionSuffix = value;
1824    }
1825
1826    /**
1827     * Set the location of the .product file
1828     * @param product the location of the .product file
1829     */

1830    public void setProduct(String JavaDoc product) {
1831        this.product = product;
1832    }
1833
1834    protected void collectElementToAssemble(IPluginEntry entryToCollect) throws CoreException {
1835        if (assemblyData == null || sourceFeatureGeneration)
1836            return;
1837        List correctConfigs = selectConfigs(entryToCollect);
1838        String JavaDoc versionRequested = entryToCollect.getVersionedIdentifier().getVersion().toString();
1839        BundleDescription effectivePlugin = null;
1840        effectivePlugin = getSite(false).getRegistry().getResolvedBundle(entryToCollect.getVersionedIdentifier().getIdentifier(), versionRequested);
1841        for (Iterator iter = correctConfigs.iterator(); iter.hasNext();) {
1842            assemblyData.addPlugin((Config) iter.next(), effectivePlugin);
1843        }
1844    }
1845
1846    // Create a feature object representing a source feature based on the featureExample
1847
private Feature createSourceFeature(Feature featureExample) throws CoreException {
1848        BuildTimeFeature result = new BuildTimeFeature();
1849        result.setFeatureIdentifier(computeSourceFeatureName(featureExample, false));
1850        result.setFeatureVersion(featureExample.getVersionedIdentifier().getVersion().toString());
1851        result.setLabel(featureExample.getLabelNonLocalized());
1852        result.setProvider(featureExample.getProviderNonLocalized());
1853        result.setImageURLString(featureExample.getImageURLString());
1854        result.setInstallHandlerModel(featureExample.getInstallHandlerModel());
1855        result.setDescriptionModel(featureExample.getDescriptionModel());
1856        result.setCopyrightModel(featureExample.getCopyrightModel());
1857        result.setLicenseModel(featureExample.getLicenseModel());
1858        result.setUpdateSiteEntryModel(featureExample.getUpdateSiteEntryModel());
1859        URLEntryModel[] siteEntries = featureExample.getDiscoverySiteEntryModels();
1860        result.setDiscoverySiteEntryModels((siteEntries == null || siteEntries.length == 0) ? null : siteEntries);
1861        result.setOS(featureExample.getOS());
1862        result.setArch(featureExample.getOSArch());
1863        result.setWS(featureExample.getWS());
1864        int contextLength = featureExample instanceof BuildTimeFeature ? ((BuildTimeFeature) featureExample).getContextQualifierLength() : -1;
1865        result.setContextQualifierLength(contextLength);
1866        return result;
1867    }
1868
1869    private void writeSourceFeature() throws CoreException {
1870        String JavaDoc sourceFeatureDir = workingDirectory + '/' + DEFAULT_FEATURE_LOCATION + '/' + sourceFeatureFullName;
1871        File sourceDir = new File(sourceFeatureDir);
1872        sourceDir.mkdirs();
1873        // write the source feature to the feature.xml
1874
File file = new File(sourceFeatureDir + '/' + Constants.FEATURE_FILENAME_DESCRIPTOR);
1875        try {
1876            SourceFeatureWriter writer = new SourceFeatureWriter(new BufferedOutputStream(new FileOutputStream(file)), sourceFeature, this);
1877            try {
1878                writer.printFeature();
1879            } finally {
1880                writer.close();
1881            }
1882        } catch (IOException e) {
1883            String JavaDoc message = NLS.bind(Messages.error_creatingFeature, sourceFeature.getFeatureIdentifier());
1884            throw new CoreException(new Status(IStatus.OK, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1885        }
1886        Collection copiedFiles = Utils.copyFiles(featureRootLocation + '/' + "sourceTemplateFeature", sourceFeatureDir); //$NON-NLS-1$
1887
if (copiedFiles.contains(Constants.FEATURE_FILENAME_DESCRIPTOR)) {
1888            //we overwrote our feature.xml with a template, replace the version
1889
replaceXMLAttribute(sourceFeatureDir + '/' + Constants.FEATURE_FILENAME_DESCRIPTOR, FEATURE_START_TAG, VERSION, sourceFeature.getFeatureVersion());
1890        }
1891        File buildProperty = new File(sourceFeatureDir + '/' + PROPERTIES_FILE);
1892        if (buildProperty.exists()) {//If a build.properties file already exist then we don't override it.
1893
getSite(false).addFeatureReferenceModel(sourceDir);
1894            return;
1895        }
1896        copiedFiles.add(Constants.FEATURE_FILENAME_DESCRIPTOR); //Because the feature.xml is not copied, we need to add it to the file
1897
Properties sourceBuildProperties = new Properties();
1898        sourceBuildProperties.put(PROPERTY_BIN_INCLUDES, Utils.getStringFromCollection(copiedFiles, ",")); //$NON-NLS-1$
1899
OutputStream output = null;
1900        try {
1901            output = new BufferedOutputStream(new FileOutputStream(buildProperty));
1902            try {
1903                sourceBuildProperties.store(output, null);
1904            } finally {
1905                output.close();
1906            }
1907        } catch (FileNotFoundException e) {
1908            String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1909            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1910        } catch (IOException e) {
1911            String JavaDoc message = NLS.bind(Messages.exception_writingFile, buildProperty.getAbsolutePath());
1912            throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
1913        }
1914        getSite(false).addFeatureReferenceModel(sourceDir);
1915    }
1916
1917    private void replaceManifestValue(String JavaDoc location, String JavaDoc attribute, String JavaDoc newVersion) {
1918        Manifest JavaDoc manifest = null;
1919        try {
1920            InputStream is = new BufferedInputStream(new FileInputStream(location));
1921            try {
1922                manifest = new Manifest JavaDoc(is);
1923            } finally {
1924                is.close();
1925            }
1926        } catch (IOException e) {
1927            return;
1928        }
1929
1930        manifest.getMainAttributes().put(new Attributes.Name JavaDoc(attribute), newVersion);
1931
1932        OutputStream os = null;
1933        try {
1934            os = new BufferedOutputStream(new FileOutputStream(location));
1935            try {
1936                manifest.write(os);
1937            } finally {
1938                os.close();
1939            }
1940        } catch (IOException e1) {
1941            //ignore
1942
}
1943    }
1944
1945    private void replaceXMLAttribute(String JavaDoc location, String JavaDoc tag, String JavaDoc attr, String JavaDoc newValue) {
1946        File featureFile = new File(location);
1947        if (!featureFile.exists())
1948            return;
1949
1950        StringBuffer JavaDoc buffer = null;
1951        try {
1952            buffer = readFile(featureFile);
1953        } catch (IOException e) {
1954            return;
1955        }
1956
1957        int startComment = scan(buffer, 0, COMMENT_START_TAG);
1958        int endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
1959        int startTag = scan(buffer, 0, tag);
1960        while (startComment != -1 && startTag > startComment && startTag < endComment) {
1961            startTag = scan(buffer, endComment, tag);
1962            startComment = scan(buffer, endComment, COMMENT_START_TAG);
1963            endComment = startComment > -1 ? scan(buffer, startComment, COMMENT_END_TAG) : -1;
1964        }
1965        if (startTag == -1)
1966            return;
1967        int endTag = scan(buffer, startTag, ">"); //$NON-NLS-1$
1968
boolean attrFound = false;
1969        while (!attrFound) {
1970            int startAttributeWord = scan(buffer, startTag, attr);
1971            if (startAttributeWord == -1 || startAttributeWord > endTag)
1972                return;
1973            if (!Character.isWhitespace(buffer.charAt(startAttributeWord - 1))) {
1974                startTag = startAttributeWord + attr.length();
1975                continue;
1976            }
1977            //Verify that the word found is the actual attribute
1978
int endAttributeWord = startAttributeWord + attr.length();
1979            while (Character.isWhitespace(buffer.charAt(endAttributeWord)) && endAttributeWord < endTag) {
1980                endAttributeWord++;
1981            }
1982            if (endAttributeWord > endTag) { //attribute has not been found
1983
return;
1984            }
1985
1986            if (buffer.charAt(endAttributeWord) != '=') {
1987                startTag = endAttributeWord;
1988                continue;
1989            }
1990
1991            int startVersionId = scan(buffer, startAttributeWord + 1, "\""); //$NON-NLS-1$
1992
int endVersionId = scan(buffer, startVersionId + 1, "\""); //$NON-NLS-1$
1993
buffer.replace(startVersionId + 1, endVersionId, newValue);
1994            attrFound = true;
1995        }
1996        if (attrFound) {
1997            try {
1998                Utils.transferStreams(new ByteArrayInputStream(buffer.toString().getBytes()), new FileOutputStream(featureFile));
1999            } catch (IOException e) {
2000                //ignore
2001
}
2002        }
2003    }
2004
2005}
Popular Tags