blob: 8e78aad6e95fe56c10d37348bd8560ee0544ed92 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM - Initial API and implementation
* G&H Softwareentwicklung GmbH - internationalization implementation (bug 150933)
*******************************************************************************/
package org.eclipse.pde.internal.build.builder;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.build.Constants;
import org.eclipse.pde.internal.build.*;
import org.eclipse.pde.internal.build.ant.AntScript;
import org.eclipse.pde.internal.build.ant.FileSet;
import org.eclipse.pde.internal.build.site.BuildTimeFeature;
public class FeatureBuildScriptGenerator extends AbstractScriptGenerator {
protected BuildTimeFeature feature;
protected Properties buildProperties;
//protected boolean analyseIncludedFeatures = false;
// private boolean generateJnlp = false;
// private boolean signJars = false;
// private String product = null;
private BuildDirector director;
private boolean generateProductFiles = true;
protected String featureFolderName;
protected String featureTempFolder;
protected String featureFullName;
protected String featureRootLocation;
protected String sourceFeatureFullNameVersioned;
private String customFeatureCallbacks = null;
private String customCallbacksBuildpath = null;
private String customCallbacksFailOnError = null;
private String customCallbacksInheritAll = null;
private BuildTimeFeature licenseFeature;
public FeatureBuildScriptGenerator(BuildTimeFeature feature) {
this.feature = feature;
featureRootLocation = feature.getRootLocation();
}
public void setDirector(BuildDirector director) {
this.director = director;
}
private void initializeVariables() throws CoreException {
featureFullName = feature.getId() + "_" + feature.getVersion(); //$NON-NLS-1$
featureFolderName = DEFAULT_FEATURE_LOCATION + '/' + featureFullName;
featureTempFolder = Utils.getPropertyFormat(PROPERTY_FEATURE_TEMP_FOLDER);
Properties properties = getBuildProperties();
customFeatureCallbacks = properties.getProperty(PROPERTY_CUSTOM_BUILD_CALLBACKS);
if (TRUE.equalsIgnoreCase(customFeatureCallbacks))
customFeatureCallbacks = DEFAULT_CUSTOM_BUILD_CALLBACKS_FILE;
else if (FALSE.equalsIgnoreCase(customFeatureCallbacks))
customFeatureCallbacks = null;
customCallbacksBuildpath = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_BUILDPATH, "."); //$NON-NLS-1$
customCallbacksFailOnError = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_FAILONERROR, FALSE);
customCallbacksInheritAll = properties.getProperty(PROPERTY_CUSTOM_CALLBACKS_INHERITALL);
String sourceFeatureName = getBuildProperties().getProperty(PROPERTY_SOURCE_FEATURE_NAME);
if (sourceFeatureName == null)
sourceFeatureName = feature.getId().endsWith(".source") ? feature.getId() : feature.getId() + ".source"; //$NON-NLS-1$ //$NON-NLS-2$
sourceFeatureFullNameVersioned = sourceFeatureName + "_" + feature.getVersion(); //$NON-NLS-1$
}
@Override
public void generate() throws CoreException {
if (feature.isBinary())
return;
if (getBuildProperties() == MissingProperties.getInstance() || AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE)) {
feature.setBinary(true);
return;
}
initializeVariables();
// if the feature defines its own custom script, we do not generate a
// new one but we do try to update the version number
boolean custom = TRUE.equalsIgnoreCase((String) getBuildProperties().get(PROPERTY_CUSTOM));
File customBuildFile = null;
if (custom) {
customBuildFile = new File(featureRootLocation, DEFAULT_BUILD_SCRIPT_FILENAME);
if (!customBuildFile.exists()) {
String message = NLS.bind(Messages.error_missingCustomBuildFile, customBuildFile);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, null));
}
/* need to do root files here because we won't be doing the gatherBinParts where it normally happens */
List<Config> configs = getConfigInfos();
for (Iterator<Config> iter = configs.iterator(); iter.hasNext();) {
director.getAssemblyData().addRootFileProvider(iter.next(), feature);
}
//Feature had a custom build script, we need to update the version in it.
//Do it here after generateChildrenScripts since there may have been a suffix generated.
try {
Utils.updateVersion(customBuildFile, PROPERTY_FEATURE_VERSION_SUFFIX, feature.getVersion());
} catch (IOException e) {
String message = NLS.bind(Messages.exception_writeScript, customBuildFile);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, e));
}
} else {
openScript(featureRootLocation, DEFAULT_BUILD_SCRIPT_FILENAME);
try {
generateBuildScript();
} finally {
closeScript();
}
}
}
/**
* Main call for generating the script.
*
* @throws CoreException
*/
private void generateBuildScript() throws CoreException {
if (BundleHelper.getDefault().isDebugging())
System.out.println("Generating feature " + featureFullName); //$NON-NLS-1$
generatePrologue();
generateAllPluginsTarget();
generateAllFeaturesTarget();
generateUpdateFeatureFile();
generateAllChildrenTarget();
generateChildrenTarget();
generateBuildJarsTarget();
generateBuildZipsTarget();
generateBuildUpdateJarTarget();
generatePublishBinPartsTarget();
generateGatherBinPartsTarget();
generateZipDistributionWholeTarget();
generateZipSourcesTarget();
generateZipLogsTarget();
generateCleanTarget();
generateRefreshTarget();
generateGatherSourcesTarget();
generateGatherLogsTarget();
generateEpilogue();
}
/**
* Method generateGatherSource. Used to enable the recursive call of
* gathering the sources for the features
*/
private void generateGatherSourcesTarget() {
script.printTargetDeclaration(TARGET_GATHER_SOURCES, null, null, null, null);
Map<String, String> params = new HashMap<>(2);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_FEATURE_TEMP_FOLDER) + '/' + DEFAULT_PLUGIN_LOCATION + '/' + sourceFeatureFullNameVersioned + '/' + "src"); //$NON-NLS-1$
params.put(PROPERTY_TARGET, TARGET_GATHER_SOURCES);
script.printAntCallTask(TARGET_CHILDREN, true, params);
script.printTargetEnd();
}
/**
* Method generateGatherSource. Used to enable the recursive call of
* gathering the sources for the features
*/
private void generateGatherLogsTarget() {
script.println();
script.printTargetDeclaration(TARGET_GATHER_LOGS, TARGET_INIT, null, null, null);
String destinationTempFolder = new Path(featureTempFolder).append(DEFAULT_PLUGIN_LOCATION).toString();
script.printMkdirTask(destinationTempFolder);
script.printProperty(PROPERTY_DESTINATION_TEMP_FOLDER, destinationTempFolder);
script.printConditionIsSet(PROPERTY_LOG_EXTENSION_PARAM, PROPERTY_LOG_EXTENSION, PROPERTY_LOG_EXTENSION, PROPERTY_LOG_EXTENSION_PARAM);
Map<String, String> params = new HashMap<>(3);
params.put(PROPERTY_TARGET, TARGET_GATHER_LOGS);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, destinationTempFolder);
params.put(Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION_PARAM), Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION));
script.printAntCallTask(TARGET_ALL_CHILDREN, false, params);
script.printTargetEnd();
}
private void generateUpdateFeatureFile() {
script.printTargetDeclaration(TARGET_UPDATE_FEATURE_FILE, TARGET_INIT, null, null, null);
script.printTargetEnd();
}
/**
* Add the <code>build.zips</code> target to the given Ant script.
*
* @throws CoreException
*/
private void generateBuildZipsTarget() throws CoreException {
StringBuffer zips = new StringBuffer();
Properties props = getBuildProperties();
for (Iterator<Entry<Object, Object>> iterator = props.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<Object, Object> entry = iterator.next();
String key = (String) entry.getKey();
if (key.startsWith(PROPERTY_SOURCE_PREFIX) && key.endsWith(PROPERTY_ZIP_SUFFIX)) {
String zipName = key.substring(PROPERTY_SOURCE_PREFIX.length());
zips.append(',');
zips.append(zipName);
generateZipIndividualTarget(zipName, (String) entry.getValue());
}
}
script.println();
script.printTargetDeclaration(TARGET_BUILD_ZIPS, TARGET_INIT + zips.toString(), null, null, null);
Map<String, String> params = new HashMap<>(2);
params.put(PROPERTY_TARGET, TARGET_BUILD_ZIPS);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printTargetEnd();
}
/**
* Add a <code>zip</code> target to the given Ant script.
*
* @param zipName the name of the zip file to create
* @param source the directory name to read the files from
*/
private void generateZipIndividualTarget(String zipName, String source) {
script.println();
script.printTargetDeclaration(zipName, TARGET_INIT, null, null, null);
script.printZipTask(Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + zipName, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + source, false, false, null);
script.printTargetEnd();
}
/**
* Add the <code>clean</code> target to the given Ant script.
*/
private void generateCleanTarget() {
script.println();
script.printTargetDeclaration(TARGET_CLEAN, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_clean, feature.getId()));
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".jar", null); //$NON-NLS-1$
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".bin.dist.zip", null); //$NON-NLS-1$
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".log.zip", null); //$NON-NLS-1$
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".src.zip", null); //$NON-NLS-1$
script.printDeleteTask(featureTempFolder, null, null);
Map<String, String> params = new HashMap<>(2);
params.put(PROPERTY_TARGET, TARGET_CLEAN);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printTargetEnd();
}
/**
* Add the <code>zip.logs</code> target to the given Ant script.
*/
private void generateZipLogsTarget() {
script.println();
script.printTargetDeclaration(TARGET_ZIP_LOGS, TARGET_INIT, null, null, null);
script.printDeleteTask(featureTempFolder, null, null);
script.printMkdirTask(featureTempFolder);
script.printConditionIsSet(PROPERTY_LOG_EXTENSION_PARAM, PROPERTY_LOG_EXTENSION, PROPERTY_LOG_EXTENSION, PROPERTY_LOG_EXTENSION_PARAM);
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_INCLUDE_CHILDREN, "true"); //$NON-NLS-1$
params.put(PROPERTY_TARGET, TARGET_GATHER_LOGS);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(featureTempFolder).append(DEFAULT_PLUGIN_LOCATION).toString());
params.put(Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION_PARAM), Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION));
script.printAntCallTask(TARGET_ALL_CHILDREN, false, params);
IPath destination = new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION)).append(featureFullName + ".log.zip"); //$NON-NLS-1$
script.printZipTask(destination.toString(), featureTempFolder, true, false, null);
script.printDeleteTask(featureTempFolder, null, null);
script.printTargetEnd();
}
/**
* Add the <code>zip.sources</code> target to the given Ant script.
*/
protected void generateZipSourcesTarget() {
script.println();
script.printTargetDeclaration(TARGET_ZIP_SOURCES, TARGET_INIT, null, null, null);
script.printDeleteTask(featureTempFolder, null, null);
script.printMkdirTask(featureTempFolder);
Map<String, String> params = new HashMap<>(3);
params.put(PROPERTY_INCLUDE_CHILDREN, "true"); //$NON-NLS-1$
params.put(PROPERTY_TARGET, TARGET_GATHER_SOURCES);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, featureTempFolder + '/' + DEFAULT_PLUGIN_LOCATION + '/' + sourceFeatureFullNameVersioned + '/' + "src"); //$NON-NLS-1$
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printZipTask(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".src.zip", featureTempFolder, true, false, null); //$NON-NLS-1$
script.printDeleteTask(featureTempFolder, null, null);
script.printTargetEnd();
}
private void generatePublishBinPartsTarget() throws CoreException {
Properties properties = getBuildProperties();
Map<String, Map<String, String>> root = Utils.processRootProperties(properties, true);
Map<String, String> common = root.get(Utils.ROOT_COMMON);
for (Iterator<Config> iter = getConfigInfos().iterator(); iter.hasNext();) {
Config aConfig = iter.next();
String configKey = aConfig.toString("."); //$NON-NLS-1$
if (root.containsKey(configKey) || common.size() > 0)
director.getAssemblyData().addRootFileProvider(aConfig, feature);
}
script.println();
script.printTargetDeclaration(TARGET_PUBLISH_BIN_PARTS, TARGET_INIT, PROPERTY_P2_PUBLISH_PARTS, null, null);
String featureTemp = Utils.getPropertyFormat(PROPERTY_FEATURE_TEMP_FOLDER) + '/' + featureFolderName;
script.printMkdirTask(featureTemp);
Map<String, String> callbackParams = null;
if (customFeatureCallbacks != null) {
callbackParams = new HashMap<>(2);
callbackParams.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE)).append(DEFAULT_PLUGIN_LOCATION).toString());
callbackParams.put(PROPERTY_FEATURE_DIRECTORY, featureTemp);
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
}
String include = (String) getBuildProperties().get(PROPERTY_BIN_INCLUDES);
if (include == null || include.indexOf("feature.xml") == -1) //$NON-NLS-1$
include = (include != null ? include + "," : "") + "feature.xml"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String exclude = (String) getBuildProperties().get(PROPERTY_BIN_EXCLUDES);
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, include, null, exclude, null, null);
script.printCopyTask(null, featureTemp, new FileSet[] {fileSet}, true, true);
generateIdReplacerCall(featureTemp);
generateLicenseReplacerCall(featureTemp, customFeatureCallbacks != null);
if (customFeatureCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
}
script.println("<eclipse.gatherFeature "); //$NON-NLS-1$
script.println(" metadataRepository=\"" + Utils.getPropertyFormat(PROPERTY_P2_BUILD_REPO) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
script.println(" artifactRepository=\"" + Utils.getPropertyFormat(PROPERTY_P2_BUILD_REPO) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
if (customFeatureCallbacks != null)
script.println(" targetFolder=\"" + featureTemp + "\""); //$NON-NLS-1$ //$NON-NLS-2$
else
script.println(" buildResultFolder=\"" + featureTemp + "\""); //$NON-NLS-1$ //$NON-NLS-2$
script.println(" baseDirectory=\"${basedir}\""); //$NON-NLS-1$
if (getLicenseFeature() != null) {
IPath licenseLocation = Utils.makeRelative(new Path(getLicenseFeatureRootLocation()), new Path(featureRootLocation));
String licensePath = licenseLocation.isAbsolute() ? licenseLocation.toString() : "${basedir}/" + licenseLocation.toString(); //$NON-NLS-1$
script.println(" licenseDirectory=\"" + licensePath + "\""); //$NON-NLS-1$ //$NON-NLS-2$
}
script.println("/>"); //$NON-NLS-1$
script.printTargetEnd();
}
/**
* Add the <code>gather.bin.parts</code> target to the given Ant script
*
* @throws CoreException
*/
private void generateGatherBinPartsTarget() throws CoreException {
String include = (String) getBuildProperties().get(PROPERTY_BIN_INCLUDES);
String exclude = (String) getBuildProperties().get(PROPERTY_BIN_EXCLUDES);
String root = Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + featureFolderName;
script.println();
script.printTargetDeclaration(TARGET_GATHER_BIN_PARTS, TARGET_INIT, PROPERTY_FEATURE_BASE, null, null);
if (include != null)
script.printMkdirTask(root);
Map<String, String> callbackParams = null;
if (customFeatureCallbacks != null) {
callbackParams = new HashMap<>(2);
callbackParams.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE)).append(DEFAULT_PLUGIN_LOCATION).toString());
callbackParams.put(PROPERTY_FEATURE_DIRECTORY, root);
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
}
Map<String, String> params = new HashMap<>(2);
params.put(PROPERTY_TARGET, TARGET_GATHER_BIN_PARTS);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, new Path(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE)).append(DEFAULT_PLUGIN_LOCATION).toString());
script.printAntCallTask(TARGET_CHILDREN, true, params);
if (include != null) {
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, include, null, exclude, null, null);
script.printCopyTask(null, root, new FileSet[] {fileSet}, true, false);
// Generate the parameters for the Id Replacer.
generateIdReplacerCall(root);
generateLicenseReplacerCall(root, true);
}
generateRootFilesAndPermissionsCalls();
if (customFeatureCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, callbackParams, null);
}
script.printTargetEnd();
generateRootFilesAndPermissions();
}
private void generateIdReplacerCall(String root) throws CoreException {
String featureVersionInfo = Utils.getEntryVersionMappings(feature.getRawIncludedFeatureReferences(), getSite(false));
String pluginVersionInfo = Utils.getEntryVersionMappings(feature.getRawPluginEntries(), getSite(false));
script.println("<eclipse.idReplacer featureFilePath=\"" + AntScript.getEscaped(root) + '/' + Constants.FEATURE_FILENAME_DESCRIPTOR + "\" selfVersion=\"" + feature.getVersion() + "\" featureIds=\"" + featureVersionInfo + "\" pluginIds=\"" + pluginVersionInfo + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
private String getLicenseFeatureRootLocation() throws CoreException {
if (getLicenseFeature() != null) {
return getLicenseFeature().getRootLocation();
}
return ""; //$NON-NLS-1$
}
private BuildTimeFeature getLicenseFeature() throws CoreException {
if (licenseFeature == null) {
String licenseFeatureName = feature.getLicenseFeature();
if (licenseFeatureName == null || licenseFeatureName.length() == 0) {
return null;
}
licenseFeature = getSite(false).findFeature(licenseFeatureName, feature.getLicenseFeatureVersion(), true);
}
return licenseFeature;
}
private void generateLicenseReplacerCall(String featureRoot, boolean printCopy) throws CoreException {
if (getLicenseFeature() == null) {
return;
}
IPath licenseLocation = Utils.makeRelative(new Path(getLicenseFeatureRootLocation()), new Path(featureRootLocation));
String licensePath = licenseLocation.isAbsolute() ? licenseLocation.toString() : "${basedir}/" + licenseLocation.toString(); //$NON-NLS-1$
if (printCopy) {
String include, exclude;
if (getLicenseFeature().isBinary()) {
include = "**"; //$NON-NLS-1$
exclude = "META-INF/"; //$NON-NLS-1$
} else {
include = (String) getBuildProperties(getLicenseFeatureRootLocation()).get(PROPERTY_BIN_INCLUDES);
exclude = (String) getBuildProperties(getLicenseFeatureRootLocation()).get(PROPERTY_BIN_EXCLUDES);
}
exclude = (exclude != null ? exclude + "," : "") + IPDEBuildConstants.LICENSE_DEFAULT_EXCLUDES; //$NON-NLS-1$//$NON-NLS-2$
FileSet fileSet = new FileSet(licensePath, null, include, null, exclude, null, null);
script.printCopyTask(null, featureRoot, new FileSet[] {fileSet}, true, true);
}
script.println("<eclipse.licenseReplacer featureFilePath=\"" + AntScript.getEscaped(featureRoot) + "\" licenseFilePath=\"" + AntScript.getEscaped(licensePath) + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
*
*/
private void generateRootFilesAndPermissionsCalls() {
Map<String, String> param = new HashMap<>(1);
param.put(TARGET_ROOT_TARGET, TARGET_ROOTFILES_PREFIX + Utils.getPropertyFormat(PROPERTY_OS) + '_' + Utils.getPropertyFormat(PROPERTY_WS) + '_' + Utils.getPropertyFormat(PROPERTY_ARCH));
script.printAntCallTask(TARGET_ROOTFILES_PREFIX, true, param);
}
/**
*
*/
private void generateRootFilesAndPermissions() throws CoreException {
boolean generateEclipseProduct = Boolean.valueOf(getBuildProperties().getProperty(IBuildPropertiesConstants.PROPERTY_GENERATE_ECLIPSEPRODUCT)).booleanValue();
String product = (generateProductFiles || generateEclipseProduct) ? director.getProduct() : null;
if (product != null) {
ProductGenerator generator = new ProductGenerator();
generator.setProduct(product);
generator.setBuildSiteFactory(siteFactory);
generator.setBuildProperties(getBuildProperties());
generator.setRoot(featureRootLocation);
generator.setWorkingDirectory(getWorkingDirectory());
generator.setAssemblyInfo(director.getAssemblyData());
try {
if (!BuildDirector.p2Gathering && generateProductFiles)
generator.generate();
else if (generateEclipseProduct)
generator.generateEclipseProduct();
} catch (CoreException e) {
//problem with the .product file
//TODO Log warning/error
}
}
script.printTargetDeclaration(TARGET_ROOTFILES_PREFIX, null, null, PROPERTY_OMIT_ROOTFILES, null);
script.printAntCallTask(Utils.getPropertyFormat(TARGET_ROOT_TARGET), true, null);
script.printTargetEnd();
script.println();
for (Iterator<Config> iter = getConfigInfos().iterator(); iter.hasNext();) {
Config aConfig = iter.next();
script.printTargetDeclaration(TARGET_ROOTFILES_PREFIX + aConfig.toString("_"), null, null, null, null); //$NON-NLS-1$
generateCopyRootFiles(aConfig);
Utils.generatePermissions(getBuildProperties(), aConfig, PROPERTY_FEATURE_BASE, script);
script.printTargetEnd();
}
script.printTargetDeclaration(TARGET_ROOTFILES_PREFIX + "group_group_group", null, null, null, null); //$NON-NLS-1$
for (Iterator<Config> iter = getConfigInfos().iterator(); iter.hasNext();) {
Config aConfig = iter.next();
script.printAntCallTask(TARGET_ROOTFILES_PREFIX + aConfig.toString("_"), true, null);//.getPropertyFormat(PROPERTY_OS) + '_' + Utils.getPropertyFormat(PROPERTY_WS) + '_' + Utils.getPropertyFormat(PROPERTY_ARCH)) //$NON-NLS-1$
}
script.printTargetEnd();
}
private void generateCopyRootFiles(Config aConfig) throws CoreException {
Properties properties = getBuildProperties();
String configKey = aConfig.toString("."); //$NON-NLS-1$
Map<String, Map<String, String>> root = Utils.processRootProperties(properties, true);
Map<String, String> foldersToCopy = root.containsKey(configKey) ? root.get(configKey) : root.get(Utils.ROOT_COMMON);
if (foldersToCopy == null || foldersToCopy.isEmpty())
return;
String configName = aConfig.toStringReplacingAny(".", ANY_STRING); //$NON-NLS-1$
String shouldOverwrite = properties.getProperty(PROPERTY_OVERWRITE_ROOTFILES, "true"); //$NON-NLS-1$
boolean overwrite = Boolean.valueOf(shouldOverwrite).booleanValue();
director.getAssemblyData().addRootFileProvider(aConfig, feature);
Object[] folders = foldersToCopy.keySet().toArray();
String fileList = null;
for (int i = 0; i < folders.length; i++) {
String folder = (String) folders[i];
if (folder.equals(Utils.ROOT_LINK) || folder.startsWith(Utils.ROOT_PERMISSIONS))
continue;
fileList = foldersToCopy.get(folder);
String[] files = Utils.getArrayFromString(fileList, ","); //$NON-NLS-1$
FileSet[] fileSet = new FileSet[files.length];
for (int j = 0; j < files.length; j++) {
String file = files[j];
String fromDir = Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/';
if (file.startsWith("absolute:")) { //$NON-NLS-1$
file = file.substring(9);
fromDir = ""; //$NON-NLS-1$
} else if (file.startsWith("license:")) { //$NON-NLS-1$
if (getLicenseFeature() == null) {
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PLUGIN_MISSING, NLS.bind(Messages.error_licenseRootWithoutLicenseRef, featureRootLocation), null));
}
file = file.substring(8);
fromDir = getLicenseFeatureRootLocation();
}
if (file.startsWith("file:")) { //$NON-NLS-1$
IPath target = new Path(file.substring(5));
fileSet[j] = new FileSet(fromDir + target.removeLastSegments(1), null, target.lastSegment(), null, null, null, null);
} else {
fileSet[j] = new FileSet(fromDir + file, null, "**", null, null, null, null); //$NON-NLS-1$
}
}
if (fileSet.length > 0) {
script.printMkdirTask(Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + configName + '/' + Utils.getPropertyFormat(PROPERTY_COLLECTING_FOLDER) + '/' + folder);
script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_FEATURE_BASE) + '/' + configName + '/' + Utils.getPropertyFormat(PROPERTY_COLLECTING_FOLDER) + '/' + folder, fileSet, true, overwrite);
}
}
}
/**
* Add the <code>build.update.jar</code> target to the given script.
*/
private void generateBuildUpdateJarTarget() {
script.println();
script.printTargetDeclaration(TARGET_BUILD_UPDATE_JAR, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_buildUpdateJar, feature.getId()));
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_TARGET, TARGET_BUILD_UPDATE_JAR);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printProperty(PROPERTY_FEATURE_BASE, featureTempFolder);
script.printDeleteTask(featureTempFolder, null, null);
script.printMkdirTask(featureTempFolder);
script.printMkdirTask(featureTempFolder + '/' + featureFolderName);
params.clear();
params.put(PROPERTY_FEATURE_BASE, featureTempFolder);
params.put(PROPERTY_OS, feature.getOS() == null ? Config.ANY : feature.getOS());
params.put(PROPERTY_WS, feature.getWS() == null ? Config.ANY : feature.getWS());
params.put(PROPERTY_ARCH, feature.getArch() == null ? Config.ANY : feature.getArch());
params.put(PROPERTY_NL, feature.getNL() == null ? Config.ANY : feature.getNL());
params.put(PROPERTY_OMIT_ROOTFILES, "true"); //$NON-NLS-1$
// Be sure to call the gather with children turned off. The only way to
// do this is
// to clear all inherited values. Must remember to setup anything that
// is really expected.
script.printAntCallTask(TARGET_GATHER_BIN_PARTS, false, params);
String jar = Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".jar"; //$NON-NLS-1$
script.printJarTask(jar, featureTempFolder + '/' + featureFolderName, null);
script.printDeleteTask(featureTempFolder, null, null);
if (director.getGenerateJnlp())
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$ );
if (director.getSignJars()) {
if (director.getGenerateJnlp()) {
script.printProperty(PROPERTY_UNSIGN, "true"); //$NON-NLS-1$
}
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$
}
script.printTargetEnd();
}
/**
* Add the <code>zip.distribution</code> target to the given Ant script.
* Zip up the whole feature.
*/
protected void generateZipDistributionWholeTarget() {
script.println();
script.printTargetDeclaration(TARGET_ZIP_DISTRIBUTION, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_zips, feature.getId()));
script.printDeleteTask(featureTempFolder, null, null);
script.printMkdirTask(featureTempFolder);
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_FEATURE_BASE, featureTempFolder);
params.put(PROPERTY_INCLUDE_CHILDREN, TRUE);
params.put(PROPERTY_OS, feature.getOS() == null ? Config.ANY : feature.getOS());
params.put(PROPERTY_WS, feature.getWS() == null ? Config.ANY : feature.getWS());
params.put(PROPERTY_ARCH, feature.getArch() == null ? Config.ANY : feature.getArch());
params.put(PROPERTY_NL, feature.getNL() == null ? Config.ANY : feature.getNL());
script.printAntCallTask(TARGET_GATHER_BIN_PARTS, true, params);
script.printZipTask(Utils.getPropertyFormat(PROPERTY_FEATURE_DESTINATION) + '/' + featureFullName + ".bin.dist.zip", featureTempFolder, false, false, null); //$NON-NLS-1$
script.printDeleteTask(featureTempFolder, null, null);
script.printTargetEnd();
}
/**
* Executes a given target in all children's script files.
*/
private void generateAllChildrenTarget() {
StringBuffer depends = new StringBuffer();
depends.append(TARGET_INIT);
depends.append(',');
depends.append(TARGET_ALL_FEATURES);
depends.append(',');
depends.append(TARGET_ALL_PLUGINS);
depends.append(',');
depends.append(TARGET_UPDATE_FEATURE_FILE);
script.println();
script.printTargetDeclaration(TARGET_ALL_CHILDREN, depends.toString(), null, null, null);
script.printTargetEnd();
}
/**
* Target responsible for delegating target calls to plug-in's build.xml
* scripts. Plugins are sorted according to the requires chain. Fragments
* are inserted afterward
*
* @throws CoreException
*/
protected void generateAllPluginsTarget() throws CoreException {
Set<BundleDescription> plugins = computeElements();
List<BundleDescription> sortedPlugins = Utils.extractPlugins(getSite(false).getRegistry().getSortedBundles(), plugins);
script.println();
script.printTargetDeclaration(TARGET_ALL_PLUGINS, TARGET_INIT, null, null, null);
Set<BundleDescription> writtenCalls = new HashSet<>(sortedPlugins.size());
for (Iterator<BundleDescription> iter = sortedPlugins.iterator(); iter.hasNext();) {
BundleDescription current = iter.next();
//If it is not a compiled element, then we don't generate a call
Properties bundleProperties = (Properties) current.getUserObject();
if (bundleProperties == null || bundleProperties.get(IS_COMPILED) == null || bundleProperties.get(IS_COMPILED) == Boolean.FALSE)
continue;
// Get the os / ws / arch to pass as a parameter to the plugin
if (writtenCalls.contains(current))
continue;
writtenCalls.add(current);
FeatureEntry[] entries = Utils.getPluginEntry(feature, current.getSymbolicName(), false); //TODO This can be improved to use the value from the user object in the bundleDescription
for (int j = 0; j < entries.length; j++) {
List<Config> list = director.selectConfigs(entries[j]);
if (list.size() == 0)
continue;
Map<String, String> params = null;
Config aMatchingConfig = list.get(0);
params = new HashMap<>(3);
if (!aMatchingConfig.getOs().equals(Config.ANY))
params.put(PROPERTY_OS, aMatchingConfig.getOs());
if (!aMatchingConfig.getWs().equals(Config.ANY))
params.put(PROPERTY_WS, aMatchingConfig.getWs());
if (!aMatchingConfig.getArch().equals(Config.ANY))
params.put(PROPERTY_ARCH, aMatchingConfig.getArch());
IPath location = Utils.makeRelative(new Path(getLocation(current)), new Path(featureRootLocation));
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toString(), Utils.getPropertyFormat(PROPERTY_TARGET), null, null, params);
}
}
script.printTargetEnd();
}
protected Set<BundleDescription> computeElements() throws CoreException {
Set<BundleDescription> computedElements = new LinkedHashSet<>(5);
FeatureEntry[] pluginList = feature.getPluginEntries();
for (int i = 0; i < pluginList.length; i++) {
FeatureEntry entry = pluginList[i];
BundleDescription model;
if (director.selectConfigs(entry).size() == 0)
continue;
String versionRequested = entry.getVersion();
model = getSite(false).getRegistry().getResolvedBundle(entry.getId(), versionRequested);
if (model == null) {
String message = NLS.bind(Messages.exception_missingPlugin, entry.getId() + "_" + entry.getVersion()); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_PLUGIN_MISSING, message, null));
}
computedElements.add(model);
}
return computedElements;
}
private void generateAllFeaturesTarget() throws CoreException {
script.printTargetDeclaration(TARGET_ALL_FEATURES, TARGET_INIT, null, null, null);
//if (analyseIncludedFeatures) {
FeatureEntry[] features = feature.getIncludedFeatureReferences();
for (int i = 0; i < features.length; i++) {
String featureId = features[i].getId();
String versionId = features[i].getVersion();
BuildTimeFeature includedFeature = getSite(false).findFeature(featureId, versionId, false);
if (includedFeature == null) {
if (features[i].isOptional())
continue;
String message = NLS.bind(Messages.exception_missingFeature, featureId + ' ' + versionId);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, null));
}
if (includedFeature.isBinary())
continue;
String includedFeatureDirectory = includedFeature.getRootLocation();
IPath location = Utils.makeRelative(new Path(includedFeatureDirectory), new Path(featureRootLocation));
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toString(), Utils.getPropertyFormat(PROPERTY_TARGET), null, null, null);
}
//}
script.printTargetEnd();
}
/**
* Just ends the script.
*/
private void generateEpilogue() {
script.println();
script.printProjectEnd();
}
/**
* Defines, the XML declaration, Ant project and init target.
*/
private void generatePrologue() {
script.printProjectDeclaration(feature.getId(), TARGET_BUILD_UPDATE_JAR, "."); //$NON-NLS-1$
script.println();
script.printTargetDeclaration(TARGET_INIT, null, null, null, null);
script.printProperty(PROPERTY_FEATURE_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + PROPERTY_FEATURE_TEMP_FOLDER);
script.printProperty(PROPERTY_FEATURE_DESTINATION, Utils.getPropertyFormat(PROPERTY_BASEDIR));
script.printProperty(PROPERTY_P2_BUILD_REPO, "file:" + Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + "/buildRepo"); //$NON-NLS-1$ //$NON-NLS-2$
script.printConditionIsTrue(PROPERTY_P2_PUBLISH_PARTS, TRUE, Utils.getPropertyFormat(PROPERTY_P2_GATHERING));
if (customFeatureCallbacks != null) {
script.printAvailableTask(PROPERTY_CUSTOM_BUILD_CALLBACKS, customCallbacksBuildpath + '/' + customFeatureCallbacks, customFeatureCallbacks);
}
script.printTargetEnd();
}
/**
* Return a properties object constructed from the build.properties file
* for the given feature. If no file exists, then an empty properties
* object is returned.
*
* @return Properties the feature's build.properties
* @throws CoreException
*/
protected Properties getBuildProperties() throws CoreException {
if (buildProperties == null)
buildProperties = readProperties(featureRootLocation, PROPERTIES_FILE, director.isIgnoreMissingPropertiesFile() ? IStatus.OK : IStatus.WARNING);
return buildProperties;
}
/**
* Return a properties object constructed from the build.properties file
* for the given feature. If no file exists, then an empty properties
* object is returned.
*
* @return Properties the feature's build.properties
* @throws CoreException
*/
protected Properties getBuildProperties(String featureLocation) throws CoreException {
return readProperties(featureLocation, PROPERTIES_FILE, director.isIgnoreMissingPropertiesFile() ? IStatus.OK : IStatus.WARNING);
}
/**
* Add the <code>children</code> target to the given Ant script.
* Delegates some target call to all-template only if the property
* includeChildren is set.
*/
private void generateChildrenTarget() {
script.println();
script.printTargetDeclaration(TARGET_CHILDREN, null, PROPERTY_INCLUDE_CHILDREN, null, null);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, null);
script.printTargetEnd();
}
/**
* Add the <code>build.jars</code> target to the given Ant script.
*/
private void generateBuildJarsTarget() {
script.println();
script.printTargetDeclaration(TARGET_BUILD_JARS, TARGET_INIT, null, null, NLS.bind(Messages.build_feature_buildJars, feature.getId()));
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_TARGET, TARGET_BUILD_JARS);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printTargetEnd();
script.println();
script.printTargetDeclaration(TARGET_BUILD_SOURCES, TARGET_INIT, null, null, null);
params.clear();
params.put(PROPERTY_TARGET, TARGET_BUILD_SOURCES);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printTargetEnd();
}
/**
* Add the <code>refresh</code> target to the given Ant script.
*/
private void generateRefreshTarget() {
script.println();
script.printTargetDeclaration(TARGET_REFRESH, TARGET_INIT, PROPERTY_ECLIPSE_RUNNING, null, NLS.bind(Messages.build_feature_refresh, feature.getId()));
script.printConvertPathTask(new Path(featureRootLocation).removeLastSegments(0).toOSString().replace('\\', '/'), PROPERTY_RESOURCE_PATH, false);
script.printRefreshLocalTask(Utils.getPropertyFormat(PROPERTY_RESOURCE_PATH), "infinite"); //$NON-NLS-1$
Map<String, String> params = new HashMap<>(2);
params.put(PROPERTY_TARGET, TARGET_REFRESH);
script.printAntCallTask(TARGET_ALL_CHILDREN, true, params);
script.printTargetEnd();
}
public void setGenerateProductFiles(boolean generateProductFiles) {
this.generateProductFiles = generateProductFiles;
}
}