blob: 5e443608ef87d61954a6fe78a919077024bb4acd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2019 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 Prosyst - create proper
* OSGi bundles (bug 174157)
******************************************************************************/
package org.eclipse.pde.internal.build.builder;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.jar.JarFile;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.osgi.service.resolver.*;
import org.eclipse.osgi.util.ManifestElement;
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.*;
import org.eclipse.pde.internal.build.builder.ClasspathComputer3_0.ClasspathElement;
import org.eclipse.pde.internal.build.site.ProfileManager;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;
/**
* Generic class for generating scripts for plug-ins and fragments.
*/
public class ModelBuildScriptGenerator extends AbstractBuildScriptGenerator {
public static final String SRC_ZIP = "src.zip"; //$NON-NLS-1$
public static final String EXPANDED_DOT = "@dot"; //$NON-NLS-1$
public static final String DOT = "."; //$NON-NLS-1$
/**
* Represents a entry that must be compiled and which is listed in the build.properties file.
*/
static public class CompiledEntry {
static public final byte JAR = 0;
static public final byte FOLDER = 1;
private final String name;
private String resolvedName;
private final String[] source;
private final String[] output;
private final String[] extraClasspath;
private final String excludedFromJar;
byte type;
protected CompiledEntry(String entryName, String[] entrySource, String[] entryOutput, String[] entryExtraClasspath, String excludedFromJar, byte entryType) {
this.name = entryName;
this.source = entrySource;
this.output = entryOutput;
this.extraClasspath = entryExtraClasspath;
this.type = entryType;
this.excludedFromJar = excludedFromJar;
}
public String getName(boolean resolved) {
if (!resolved)
return name;
if (resolvedName == null)
resolvedName = replaceVariables(name, true);
return resolvedName;
}
protected String[] getSource() {
return source;
}
public String[] getOutput() {
return output;
}
public String[] getExtraClasspath() {
return extraClasspath;
}
public byte getType() {
return type;
}
public String getExcludedFromJar() {
return excludedFromJar;
}
}
/**
* Bundle for which we are generating the script.
*/
protected BundleDescription model;
/**
* PluginEntry corresponding to the bundle
*/
private FeatureEntry associatedEntry;
protected String fullName;
protected String pluginZipDestination;
protected String pluginUpdateJarDestination;
private BuildDirector featureGenerator;
/** constants */
protected final String PLUGIN_DESTINATION = Utils.getPropertyFormat(PROPERTY_PLUGIN_DESTINATION);
private Properties permissionProperties;
private String propertiesFileName = PROPERTIES_FILE;
private String buildScriptFileName = DEFAULT_BUILD_SCRIPT_FILENAME;
private String customBuildCallbacks = null;
private String customCallbacksBuildpath = null;
private String customCallbacksFailOnError = null;
private String customCallbacksInheritAll = null;
private String warningProperties = null;
// array of extensions of recognized source files (eg- *.java, *.aj, etc)
private String[] sourceFileExtensions;
//This list is initialized by the generateBuildJarsTarget
private ArrayList<CompiledEntry> compiledJarNames;
private boolean dotOnTheClasspath = false;
private boolean binaryPlugin = false;
private boolean signJars = false;
private Map<String, Set<IPath>> workspaceOutputFolders = null;
private boolean generateErrorPropertyAttribute = true;
private boolean sourceReferences = false;
/**
* @see AbstractScriptGenerator#generate()
*/
@Override
public void generate() throws CoreException {
//If it is a binary plugin, then we don't generate scripts
if (binaryPlugin)
return;
if (model == null) {
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ELEMENT_MISSING, Messages.error_missingElement, null));
}
// If the the plugin we want to generate is a source plugin, and the feature that required the generation of this plugin is not being asked to build the source
// we want to leave. This is particularly usefull for the case of the pde.source building (at least for now since the source of pde is not in a feature)
// if (featureGenerator != null && featureGenerator.getBuildProperties().containsKey(GENERATION_SOURCE_PLUGIN_PREFIX + model.getSymbolicName()))
// return;
initializeVariables();
if (BundleHelper.getDefault().isDebugging())
System.out.println("Generating plugin " + model.getSymbolicName()); //$NON-NLS-1$
String custom = (String) getBuildProperties().get(PROPERTY_CUSTOM);
if (custom != null && custom.equalsIgnoreCase("true")) { //$NON-NLS-1$
updateExistingScript();
return;
}
openScript(getLocation(model), buildScriptFileName);
try {
generateBuildScript();
} finally {
closeScript();
}
}
public static String getNormalizedName(BundleDescription bundle) {
return bundle.getSymbolicName() + '_' + bundle.getVersion();
}
private void initializeVariables() throws CoreException {
fullName = getNormalizedName(model);
pluginZipDestination = PLUGIN_DESTINATION + '/' + fullName + ".zip"; //$NON-NLS-1$
pluginUpdateJarDestination = PLUGIN_DESTINATION + '/' + fullName + ".jar"; //$NON-NLS-1$
String[] classpathInfo = getClasspathEntries(model);
dotOnTheClasspath = specialDotProcessing(getBuildProperties(), classpathInfo);
generateErrorPropertyAttribute = shouldGenerateErrorAttribute();
//Persist this information for use in the assemble script generation
Properties bundleProperties = (Properties) model.getUserObject();
bundleProperties.put(WITH_DOT, Boolean.valueOf(dotOnTheClasspath));
Properties properties = getBuildProperties();
customBuildCallbacks = properties.getProperty(PROPERTY_CUSTOM_BUILD_CALLBACKS);
if (TRUE.equalsIgnoreCase(customBuildCallbacks))
customBuildCallbacks = DEFAULT_CUSTOM_BUILD_CALLBACKS_FILE;
else if (FALSE.equalsIgnoreCase(customBuildCallbacks))
customBuildCallbacks = 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);
// Bug 303960 determine all source files recognized in this bundle
String sourceFileExtensionsStr = properties.getProperty(PROPERTY_SOURCE_FILE_EXTENSIONS);
if (sourceFileExtensionsStr == null) {
sourceFileExtensions = DEFAULT_SOURCE_FILE_EXTENSIONS;
} else {
String[] sourceFileExtensionsArr = sourceFileExtensionsStr.split(","); //$NON-NLS-1$
sourceFileExtensions = new String[sourceFileExtensionsArr.length];
for (int i = 0; i < sourceFileExtensionsArr.length; i++) {
sourceFileExtensions[i] = sourceFileExtensionsArr[i].trim();
}
}
if (featureGenerator != null && featureGenerator.useWorkspaceBinaries() && havePDEUIState()) {
PDEUIStateWrapper wrapper = getSite(false).getSiteContentProvider().getInitialState();
if (wrapper != null && wrapper.getOutputFolders() != null) {
Map<String, Map<String, Set<IPath>>> folders = wrapper.getOutputFolders();
if (folders.containsKey(model.getSymbolicName())) {
workspaceOutputFolders = folders.get(model.getSymbolicName());
}
}
}
String projectWarningSettings = getBuildProperties().getProperty(PROPERTY_PROJECT_SETTINGS);
if (Boolean.valueOf(projectWarningSettings).booleanValue()) {
//find default prefs file
if (new File(model.getLocation(), JDT_CORE_PREFS).exists())
warningProperties = JDT_CORE_PREFS;
} else if (projectWarningSettings != null && !FALSE.equalsIgnoreCase(projectWarningSettings)) {
if (new File(model.getLocation(), projectWarningSettings).exists())
warningProperties = projectWarningSettings;
}
}
protected static boolean findAndReplaceDot(String[] classpathInfo) {
for (int i = 0; i < classpathInfo.length; i++) {
if (DOT.equals(classpathInfo[i])) {
classpathInfo[i] = EXPANDED_DOT;
return true;
}
}
return false;
}
public static boolean specialDotProcessing(Properties properties, String[] classpathInfo) {
findAndReplaceDot(classpathInfo);
String outputValue = properties.getProperty(PROPERTY_OUTPUT_PREFIX + DOT);
if (outputValue != null) {
properties.setProperty(PROPERTY_OUTPUT_PREFIX + EXPANDED_DOT, outputValue);
properties.remove(PROPERTY_OUTPUT_PREFIX + DOT);
}
String sourceFolder = properties.getProperty(PROPERTY_SOURCE_PREFIX + DOT);
if (sourceFolder != null) {
properties.setProperty(PROPERTY_SOURCE_PREFIX + EXPANDED_DOT, sourceFolder);
properties.remove(PROPERTY_SOURCE_PREFIX + DOT);
String excludedFromJar = properties.getProperty(PROPERTY_EXCLUDE_PREFIX + DOT);
if (excludedFromJar != null) {
properties.setProperty(PROPERTY_EXCLUDE_PREFIX + EXPANDED_DOT, excludedFromJar);
properties.remove(PROPERTY_EXCLUDE_PREFIX + DOT);
}
String buildOrder = properties.getProperty(PROPERTY_JAR_ORDER);
if (buildOrder != null) {
String[] order = Utils.getArrayFromString(buildOrder);
for (int i = 0; i < order.length; i++)
if (order[i].equals(DOT))
order[i] = EXPANDED_DOT;
properties.setProperty(PROPERTY_JAR_ORDER, Utils.getStringFromArray(order, ",")); //$NON-NLS-1$
}
String extraEntries = properties.getProperty(PROPERTY_EXTRAPATH_PREFIX + '.');
if (extraEntries != null) {
properties.setProperty(PROPERTY_EXTRAPATH_PREFIX + EXPANDED_DOT, extraEntries);
}
String includeString = properties.getProperty(PROPERTY_BIN_INCLUDES);
if (includeString != null) {
String[] includes = Utils.getArrayFromString(includeString);
for (int i = 0; i < includes.length; i++)
if (includes[i].equals(DOT))
includes[i] = EXPANDED_DOT + '/';
properties.setProperty(PROPERTY_BIN_INCLUDES, Utils.getStringFromArray(includes, ",")); //$NON-NLS-1$
}
return true;
}
return false;
}
/**
* Main call for generating the script.
*
* @throws CoreException
*/
private void generateBuildScript() throws CoreException {
generatePrologue();
generateBuildUpdateJarTarget();
if (getBuildProperties().getProperty(SOURCE_PLUGIN, null) == null) {
generateBuildJarsTarget(model);
} else {
generateBuildJarsTargetForSourceGathering();
generateEmptyBuildSourcesTarget();
}
generatePublishBinPartsTarget();
generateGatherBinPartsTarget();
generateBuildZipsTarget();
generateGatherSourcesTarget();
generateGatherIndividualSourcesTarget();
generateCopySourcesTarget();
generateGatherLogTarget();
generateCleanTarget();
generateRefreshTarget();
generateZipPluginTarget();
generateAPIToolsTarget();
generateEpilogue();
}
/**
* Method generateEmptyBuildSourceTarget.
*/
private void generateEmptyBuildSourcesTarget() {
script.printTargetDeclaration(TARGET_BUILD_SOURCES, null, null, null, null);
script.printTargetEnd();
}
/**
* Method generateBuildJarsTargetForSourceGathering.
*/
private void generateBuildJarsTargetForSourceGathering() {
script.printTargetDeclaration(TARGET_BUILD_JARS, null, null, null, null);
compiledJarNames = new ArrayList<>(0);
if (Utils.isSourceBundle(model)) {
//We are an individual source bundle, source gathering is done in gather.bin.parts via gather.individual.sources
script.printTargetEnd();
return;
}
File previousSrcRoot = Utils.getOldSourceLocation(model);
Set<BundleDescription> pluginsToGatherSourceFrom = featureGenerator.sourceToGather.getElementEntries().get(model.getSymbolicName());
if (pluginsToGatherSourceFrom != null) {
for (Iterator<BundleDescription> iter = pluginsToGatherSourceFrom.iterator(); iter.hasNext();) {
BundleDescription plugin = iter.next();
// We are not trying to gather the source from ourself since we are generated and we know we don't have source...
if (plugin.getSymbolicName().equals(model.getSymbolicName()))
continue;
if (Utils.isBinary(plugin)) {
// this plug-in wasn't compiled, take source from the previous source plug-in
if (previousSrcRoot != null) {
File previousSrc = new File(previousSrcRoot, getNormalizedName(plugin));
if (previousSrc.exists()) {
FileSet[] fileSets = new FileSet[1];
fileSets[0] = new FileSet(previousSrc.getAbsolutePath(), null, "**/*", null, null, null, null); //$NON-NLS-1$
script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_BASEDIR) + "/src/" + previousSrc.getName(), fileSets, true, false); //$NON-NLS-1$
}
}
} else {
// gather up source that was built for this plug-in
// The two steps are required, because some plug-ins (xerces, junit, ...) don't build their source: the source already comes zipped
IPath location = Utils.makeRelative(new Path(getLocation(plugin)), new Path(getLocation(model)));
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toOSString(), TARGET_BUILD_SOURCES, null, null, null);
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_BASEDIR) + "/src"); //$NON-NLS-1$
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toOSString(), TARGET_GATHER_SOURCES, null, null, params);
}
}
}
script.printTargetEnd();
}
/**
* Add the <code>clean</code> target to the given Ant script.
*
* @throws CoreException
*/
private void generateCleanTarget() throws CoreException {
script.println();
Properties properties = getBuildProperties();
CompiledEntry[] availableJars = extractEntriesToCompile(properties);
script.printTargetDeclaration(TARGET_CLEAN, TARGET_INIT, null, null, NLS.bind(Messages.build_plugin_clean, model.getSymbolicName()));
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(3);
params.put(PROPERTY_PLUGIN_DESTINATION, PLUGIN_DESTINATION);
params.put(PROPERTY_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER));
params.put(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_CLEAN, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
for (int i = 0; i < availableJars.length; i++) {
String jarName = availableJars[i].getName(true);
String jarLocation = getJARLocation(jarName);
//avoid destructive cleans
if (jarLocation.equals("") || jarLocation.startsWith(DOT + DOT) || jarLocation.equals(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER))) //$NON-NLS-1$
continue;
if (availableJars[i].type == CompiledEntry.JAR) {
script.printDeleteTask(null, jarLocation, null);
} else {
script.printDeleteTask(jarLocation, null, null);
}
script.printDeleteTask(null, getSRCLocation(jarName), null);
}
script.printDeleteTask(null, pluginUpdateJarDestination, null);
script.printDeleteTask(null, pluginZipDestination, null);
script.printDeleteTask(Utils.getPropertyFormat(IXMLConstants.PROPERTY_TEMP_FOLDER), null, null);
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_COMPILE_PROBLEM_MARKER), TRUE, null);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_CLEAN, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
/**
* Add the <code>gather.logs</code> target to the given Ant script.
*
* @throws CoreException
*/
private void generateGatherLogTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_GATHER_LOGS, TARGET_INIT, PROPERTY_DESTINATION_TEMP_FOLDER, null, null);
IPath baseDestination = new Path(Utils.getPropertyFormat(PROPERTY_DESTINATION_TEMP_FOLDER));
baseDestination = baseDestination.append(fullName);
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(1);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, baseDestination.toString());
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_LOGS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
List<IPath> destinations = new ArrayList<>(5);
Properties properties = getBuildProperties();
CompiledEntry[] availableJars = extractEntriesToCompile(properties);
for (int i = 0; i < availableJars.length; i++) {
String name = availableJars[i].getName(true);
IPath destination = baseDestination.append(name).removeLastSegments(1); // remove the jar name
if (!destinations.contains(destination)) {
script.printMkdirTask(destination.toString());
destinations.add(destination);
}
String logFolder = (availableJars[i].getType() == CompiledEntry.FOLDER) ? getJARLocation(name) : getTempJARFolderLocation(name);
Path logPath = new Path(logFolder + Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION));
FileSet logSet = new FileSet(logPath.removeLastSegments(1).toString(), null, logPath.lastSegment(), null, null, null, null);
script.printCopyTask(null, destination.toString(), new FileSet[] {logSet}, false, false);
}
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_LOGS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
/**
*
* @param zipName
* @param source
*/
private void generateZipIndividualTarget(String zipName, String source) {
script.println();
script.printTargetDeclaration(zipName, TARGET_INIT, null, null, null);
IPath root = new Path(Utils.getPropertyFormat(IXMLConstants.PROPERTY_BASEDIR));
script.printZipTask(root.append(zipName).toString(), root.append(source).toString(), false, false, null);
script.printTargetEnd();
}
/**
* Add the <code>gather.sources</code> target to the given Ant script.
*
* @throws CoreException
*/
private void generateGatherSourcesTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_GATHER_SOURCES, TARGET_INIT, PROPERTY_DESTINATION_TEMP_FOLDER, null, null);
IPath baseDestination = new Path(Utils.getPropertyFormat(PROPERTY_DESTINATION_TEMP_FOLDER));
baseDestination = baseDestination.append(fullName);
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(1);
params.put(PROPERTY_TARGET_FOLDER, baseDestination.toString());
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
List<IPath> destinations = new ArrayList<>(5);
Properties properties = getBuildProperties();
CompiledEntry[] availableJars = extractEntriesToCompile(properties);
for (int i = 0; i < availableJars.length; i++) {
String jar = availableJars[i].getName(true);
IPath destination = baseDestination.append(jar).removeLastSegments(1); // remove the jar name
if (!destinations.contains(destination)) {
script.printMkdirTask(destination.toString());
destinations.add(destination);
}
script.printCopyTask(getSRCLocation(jar), destination.toString(), null, false, false);
}
Map<String, String> copyParams = new HashMap<>();
copyParams.put(PROPERTY_SOURCE_DESTINATION_FOLDER, baseDestination.toString());
script.printAntCallTask(TARGET_COPY_SRC_INCLUDES, true, copyParams);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
private void generateGatherIndividualSourcesTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_GATHER_INDIVIDUAL_SOURCES, TARGET_INIT, null, null, null);
IPath baseDestination = new Path(Utils.getPropertyFormat(PROPERTY_DESTINATION_TEMP_FOLDER));
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(1);
params.put(PROPERTY_TARGET_FOLDER, baseDestination.toString());
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
Map<String, String> copyParams = new HashMap<>();
copyParams.put(PROPERTY_SOURCE_DESTINATION_FOLDER, baseDestination.toString());
Properties properties = getBuildProperties();
CompiledEntry[] availableJars = extractEntriesToCompile(properties);
for (int i = 0; i < availableJars.length; i++) {
String jar = availableJars[i].getName(true);
String srcName = getSRCName(jar);
script.printAntCallTask("copy." + srcName, true, copyParams); //$NON-NLS-1$
}
script.printAntCallTask(TARGET_COPY_SRC_INCLUDES, true, copyParams);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
private void generateCopySourcesTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_COPY_SRC_INCLUDES, TARGET_INIT, null, null, null);
IPath baseDestination = new Path(Utils.getPropertyFormat(PROPERTY_SOURCE_DESTINATION_FOLDER));
String include = (String) getBuildProperties().get(PROPERTY_SRC_INCLUDES);
String exclude = (String) getBuildProperties().get(PROPERTY_SRC_EXCLUDES);
if (include != null || exclude != null) {
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, include, null, exclude, null, null);
script.printCopyTask(null, baseDestination.toString(), new FileSet[] {fileSet}, false, false);
}
script.printTargetEnd();
}
private void generateAPIToolsTarget() {
script.println();
script.printTargetDeclaration(TARGET_API_GENERATION, null, PROPERTY_GENERATE_API_DESCRIPTION, null, null);
script.printTab();
script.print("<apitooling.apigeneration "); //$NON-NLS-1$
script.printAttribute("projectName", Utils.getPropertyFormat(PROPERTY_PROJECT_NAME), true); //$NON-NLS-1$
script.printAttribute("project", Utils.getPropertyFormat(PROPERTY_PROJECT_LOCATION), true); //$NON-NLS-1$
script.printAttribute("binary", Utils.getPropertyFormat(PROPERTY_BINARY_FOLDERS), true); //$NON-NLS-1$
script.printAttribute("target", Utils.getPropertyFormat(PROPERTY_TARGET_FOLDER), true); //$NON-NLS-1$
script.printAttribute("extramanifests", Utils.getPropertyFormat(PROPERTY_EXTRA_MANIFESTS), true); //$NON-NLS-1$
script.printAttribute("allownonapiproject", Utils.getPropertyFormat(PROPERTY_ALLOW_NON_API_PROJECT), false); //$NON-NLS-1$
script.println("/>"); //$NON-NLS-1$
script.printTargetEnd();
}
private void generateAPIToolsCall(String[] binaries, boolean dotIncluded, String target) throws CoreException {
Set<String> classpathEntries = new HashSet<>(Arrays.asList(getClasspathEntries(model)));
StringBuffer binaryFolders = new StringBuffer();
if (workspaceOutputFolders != null && workspaceOutputFolders.size() > 0) {
for (Iterator<String> iterator = workspaceOutputFolders.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
Set<IPath> paths = workspaceOutputFolders.get(key);
for (Iterator<IPath> iterator2 = paths.iterator(); iterator2.hasNext();) {
IPath path = iterator2.next();
if (binaryFolders.length() > 0)
binaryFolders.append(File.pathSeparator);
binaryFolders.append(Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + path.toString());
}
if (key.equals(DOT))
classpathEntries.remove(EXPANDED_DOT);
else
classpathEntries.remove(key);
}
} else {
for (int i = 0; i < binaries.length; i++) {
if (binaries[i] != null) {
if (i > 0)
binaryFolders.append(File.pathSeparator);
binaryFolders.append(target + '/' + binaries[i]);
classpathEntries.remove(binaries[i]);
}
}
if (dotIncluded) {
if (binaryFolders.length() > 0)
binaryFolders.append(File.pathSeparator);
binaryFolders.append(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + '/' + EXPANDED_DOT);
classpathEntries.remove(EXPANDED_DOT);
}
}
for (Iterator<String> iterator = classpathEntries.iterator(); iterator.hasNext();) {
String entry = iterator.next();
if (entry.equals(EXPANDED_DOT) || new File(model.getLocation(), entry).exists()) {
if (binaryFolders.length() > 0)
binaryFolders.append(File.pathSeparator);
if (entry.equals(EXPANDED_DOT))
binaryFolders.append(model.getLocation());
else {
binaryFolders.append(model.getLocation() + '/' + entry);
}
}
}
Map<String, String> params = new HashMap<>();
params.put(PROPERTY_PROJECT_NAME, Utils.getPropertyFormat(PROPERTY_BUNDLE_ID) + "_" + Utils.getPropertyFormat(PROPERTY_BUNDLE_VERSION)); //$NON-NLS-1$
params.put(PROPERTY_PROJECT_LOCATION, Utils.getPropertyFormat(PROPERTY_BASEDIR));
params.put(PROPERTY_BINARY_FOLDERS, binaryFolders.toString());
params.put(PROPERTY_TARGET_FOLDER, target);
HostSpecification host = model.getHost();
if (host != null && host.getSupplier() != null) {
BundleDescription hostBundle = host.getSupplier().getSupplier();
String hostLocation = hostBundle.getLocation();
String modelLocation = model.getLocation();
if (hostLocation != null && modelLocation != null) {
IPath location = null;
if (new File(hostLocation).isFile()) {
location = Utils.makeRelative(new Path(hostLocation), new Path(modelLocation));
} else {
IPath hostPath = new Path(hostLocation);
location = Utils.makeRelative(hostPath.append(JarFile.MANIFEST_NAME), new Path(modelLocation));
}
if (location.isAbsolute())
params.put(PROPERTY_EXTRA_MANIFESTS, location.toString());
else
params.put(PROPERTY_EXTRA_MANIFESTS, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + location.toString());
}
}
script.printAntCallTask(TARGET_API_GENERATION, true, params);
}
private void generatePublishBinPartsTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_PUBLISH_BIN_PARTS, TARGET_INIT, PROPERTY_P2_PUBLISH_PARTS, PROPERTY_COMPILE_PROBLEM_MARKER_EXISTS, null);
IPath destination = new Path(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
destination = destination.append(fullName);
String root = destination.toString();
script.printMkdirTask(root);
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(3);
params.put(PROPERTY_TARGET_FOLDER, root);
params.put(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
generateGatherBinParts(destination);
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
} else {
String include = (String) getBuildProperties().get(PROPERTY_BIN_INCLUDES);
String exclude = (String) getBuildProperties().get(PROPERTY_BIN_EXCLUDES);
String files = JarFile.MANIFEST_NAME + "," + Constants.PLUGIN_FILENAME_DESCRIPTOR + "," + Constants.FRAGMENT_FILENAME_DESCRIPTOR; //$NON-NLS-1$ //$NON-NLS-2$
FileSet metadata = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, files, null, exclude, null, null);
script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER), new FileSet[] {metadata}, true, true);
if (Utils.isSourceBundle(model)) {
Set<BundleDescription> pluginsToGatherSourceFrom = getPluginSourceProviders();
if (pluginsToGatherSourceFrom != null) {
for (Iterator<BundleDescription> iter = pluginsToGatherSourceFrom.iterator(); iter.hasNext();) {
BundleDescription plugin = iter.next();
IPath location = Utils.makeRelative(new Path(getLocation(plugin)), new Path(getLocation(model)));
Map<String, String> taskParams = new HashMap<>(1);
taskParams.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + "/sources"); //$NON-NLS-1$
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toOSString(), TARGET_GATHER_INDIVIDUAL_SOURCES, null, null, taskParams);
}
}
}
String[] splitIncludes = Utils.getArrayFromString(include);
genarateIdReplacementCall(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
generateAPIToolsCall(getCompiledLocations(), Utils.isStringIn(splitIncludes, EXPANDED_DOT + '/') != -1, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
}
script.println("<eclipse.gatherBundle "); //$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$
script.println(" buildResultFolder=\"" + Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
//if the feature specifies the bundle shape, or the bundle itself doesn't have a preferred shape, then use the feature shape value (true by default)
if (associatedEntry != null && (associatedEntry.unpackSet() || !Utils.hasBundleShapeHeader(model)))
script.println(" unpack=\"" + String.valueOf(associatedEntry.isUnpack()) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
if (customBuildCallbacks != null) {
script.println(" targetFolder=\"" + root + "\""); //$NON-NLS-1$ //$NON-NLS-2$
script.println("/>"); //$NON-NLS-1$
} else {
script.println(" baseDirectory=\"${basedir}\""); //$NON-NLS-1$
if (Utils.isSourceBundle(model))
script.println(" gatheredSource=\"" + Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + "/sources\""); //$NON-NLS-1$//$NON-NLS-2$
if (workspaceOutputFolders == null || workspaceOutputFolders.size() == 0 || customBuildCallbacks != null) {
script.println("/>"); //$NON-NLS-1$
} else {
//reuse workspace compiled classes
script.println(">"); //$NON-NLS-1$
for (Iterator<String> iterator = workspaceOutputFolders.keySet().iterator(); iterator.hasNext();) {
String key = iterator.next();
Set<IPath> paths = workspaceOutputFolders.get(key);
for (Iterator<IPath> pathIterator = paths.iterator(); pathIterator.hasNext();) {
IPath path = pathIterator.next();
script.printTabs();
script.print(" <outputFolder "); //$NON-NLS-1$
script.printAttribute("library", key, true); //$NON-NLS-1$
script.printAttribute("dir", Utils.getPropertyFormat(PROPERTY_BASEDIR), true); //$NON-NLS-1$
script.printAttribute("includes", path.toString() + "/**", true); //$NON-NLS-1$ //$NON-NLS-2$
script.println("/>"); //$NON-NLS-1$
}
}
script.printEndTag("eclipse.gatherBundle"); //$NON-NLS-1$
}
}
script.printTargetEnd();
}
private String[] getCompiledLocations() {
int count = 0;
String[] fileSetValues = new String[compiledJarNames.size()];
for (Iterator<CompiledEntry> iter = compiledJarNames.iterator(); iter.hasNext();) {
CompiledEntry entry = iter.next();
String formatedName = entry.getName(false) + (entry.getType() == CompiledEntry.FOLDER ? "/" : ""); //$NON-NLS-1$//$NON-NLS-2$
if (dotOnTheClasspath && formatedName.startsWith(EXPANDED_DOT)) {
continue;
}
fileSetValues[count++] = formatedName;
}
return fileSetValues;
}
/**
* Add the <code>gather.bin.parts</code> target to the given Ant script.
*
* @throws CoreException
*/
private void generateGatherBinPartsTarget() throws CoreException {
script.println();
script.printTargetDeclaration(TARGET_GATHER_BIN_PARTS, TARGET_INIT, PROPERTY_DESTINATION_TEMP_FOLDER, null, null);
IPath destination = new Path(Utils.getPropertyFormat(PROPERTY_DESTINATION_TEMP_FOLDER));
destination = destination.append(fullName);
String root = destination.toString();
script.printMkdirTask(root);
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(3);
params.put(PROPERTY_TARGET_FOLDER, root);
params.put(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
generateGatherBinParts(destination);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_GATHER_BIN_PARTS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
private void generateGatherBinParts(IPath destination) throws CoreException {
String root = destination.toString();
List<IPath> destinations = new ArrayList<>(5);
destinations.add(destination);
String include = (String) getBuildProperties().get(PROPERTY_BIN_INCLUDES);
String exclude = (String) getBuildProperties().get(PROPERTY_BIN_EXCLUDES);
//Copy only the jars that has been compiled and are listed in the includes
String[] splitIncludes = Utils.getArrayFromString(include);
String[] fileSetValues = getCompiledLocations();
boolean dotIncluded = false; //This flag indicates if . should be gathered
int pos = Utils.isStringIn(splitIncludes, EXPANDED_DOT + '/');
if (pos != -1) {
splitIncludes[pos] = null;
dotIncluded = true;
}
if (fileSetValues.length > 0 && fileSetValues[0] != null) {
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER), null, Utils.getStringFromArray(fileSetValues, ","), null, replaceVariables(exclude, true), null, null); //$NON-NLS-1$
script.printCopyTask(null, root, new FileSet[] {fileSet}, true, false);
}
//Dot on the classpath need to be copied in a special way
if (dotIncluded) {
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + '/' + EXPANDED_DOT, null, "**", null, replaceVariables(exclude, true), null, null); //$NON-NLS-1$
script.printCopyTask(null, root, new FileSet[] {fileSet}, true, false);
}
//General copy of the files listed in the includes
if (include != null || exclude != null) {
String includeSet = replaceVariables(Utils.getStringFromArray(splitIncludes, ","), true); //$NON-NLS-1$
if (includeSet != null && includeSet.length() > 0) {
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR), null, includeSet, null, replaceVariables(exclude, true), null, null);
script.printCopyTask(null, root, new FileSet[] {fileSet}, true, true);
}
}
if (Utils.isSourceBundle(model)) {
Set<BundleDescription> pluginsToGatherSourceFrom = getPluginSourceProviders();
if (pluginsToGatherSourceFrom != null) {
for (Iterator<BundleDescription> iter = pluginsToGatherSourceFrom.iterator(); iter.hasNext();) {
BundleDescription plugin = iter.next();
IPath location = Utils.makeRelative(new Path(getLocation(plugin)), new Path(getLocation(model)));
Map<String, String> taskParams = new HashMap<>(1);
taskParams.put(PROPERTY_DESTINATION_TEMP_FOLDER, root);
script.printAntTask(DEFAULT_BUILD_SCRIPT_FILENAME, location.toOSString(), TARGET_GATHER_INDIVIDUAL_SOURCES, null, null, taskParams);
}
}
}
generatePermissionProperties(root);
genarateIdReplacementCall(destination.toString());
generateAPIToolsCall(fileSetValues, dotIncluded, root);
}
private Set<BundleDescription> getPluginSourceProviders() throws CoreException {
Set<BundleDescription> pluginSet = featureGenerator.sourceToGather.getElementEntries().get(model.getSymbolicName());
if (pluginSet != null && pluginSet.size() > 0)
return pluginSet;
String sourceAttribute = getBuildProperties().getProperty(SOURCE_PLUGIN_ATTRIBUTE);
if (Boolean.valueOf(sourceAttribute).booleanValue())
return null;
String[] tokens = Utils.getArrayFromString(sourceAttribute, ";"); //$NON-NLS-1$
pluginSet = new HashSet<>();
for (int i = 0; i + 1 < tokens.length; i += 2) {
BundleDescription fromPlugin = getSite(false).getRegistry().getBundle(tokens[i], tokens[i + 1], true);
if (fromPlugin != null && !Utils.isBinary(fromPlugin))
pluginSet.add(fromPlugin);
}
return pluginSet;
}
private void genarateIdReplacementCall(String location) {
Properties bundleProperties = (Properties) model.getUserObject();
if (bundleProperties == null)
return;
String qualifier = bundleProperties.getProperty(PROPERTY_QUALIFIER);
String sourceReference = getSourceReference(bundleProperties);
if (qualifier == null && sourceReference == null)
return;
Map<String, String> arguments = new HashMap<>();
arguments.put("path", AntScript.getEscaped(location)); //$NON-NLS-1$
if (qualifier != null)
arguments.put("version", model.getVersion().toString()); //$NON-NLS-1$
if (sourceReference != null)
arguments.put("attributes", ECLIPSE_SOURCE_REF + '|' + sourceReference); //$NON-NLS-1$
script.printElement("eclipse.versionReplacer", arguments); //$NON-NLS-1$
}
private String getSourceReference(Properties bundleProperties) {
String reference = (String) bundleProperties.get(PROPERTY_SOURCE_REFERENCE);
if (!sourceReferences || reference == null)
return null;
String originalEntry = (String) bundleProperties.get(ECLIPSE_SOURCE_REF);
if (originalEntry != null) {
try {
ManifestElement[] elements = ManifestElement.parseHeader(ECLIPSE_SOURCE_REF, originalEntry);
StringBuffer newEntry = new StringBuffer();
boolean changed = false;
for (int i = 0; i < elements.length; i++) {
if (i > 0)
newEntry.append(',');
if (elements[i].getValue().equals(PDE_SOURCE_REF)) {
newEntry.append(reference);
changed = true;
} else
newEntry.append(elements[i].toString());
}
return changed ? newEntry.toString() : null; //returning null is no change
} catch (BundleException e) {
// ignore
}
} else {
return reference;
}
return null;
}
private void generatePermissionProperties(String directory) throws CoreException {
getPermissionProperties();
for (Iterator<Entry<Object, Object>> iter = permissionProperties.entrySet().iterator(); iter.hasNext();) {
Map.Entry<Object, Object> permission = iter.next();
String instruction = (String) permission.getKey();
String parameters = (String) permission.getValue();
int index;
if ((index = instruction.indexOf(PERMISSIONS)) != -1) {
generateChmodInstruction(directory, instruction.substring(index + PERMISSIONS.length() + 1), parameters);
continue;
}
if (instruction.startsWith(LINK)) {
generateLinkInstruction(directory, parameters);
}
}
}
private void generateChmodInstruction(String dir, String rights, String files) {
// TO CHECK We only consider rights specified with numbers
if (rights.equals(EXECUTABLE)) {
rights = "755"; //$NON-NLS-1$
}
script.printChmod(dir, rights, files);
}
private void generateLinkInstruction(String dir, String files) {
String[] links = Utils.getArrayFromString(files, ","); //$NON-NLS-1$
List<String> arguments = new ArrayList<>(2);
for (int i = 0; i < links.length; i += 2) {
arguments.add(links[i]);
arguments.add(links[i + 1]);
script.printExecTask("ln -s", dir, arguments, "Linux"); //$NON-NLS-1$ //$NON-NLS-2$
arguments.clear();
}
}
protected Properties getPermissionProperties() throws CoreException {
if (permissionProperties == null) {
permissionProperties = readProperties(getLocation(model), PERMISSIONS_FILE, IStatus.INFO);
}
return permissionProperties;
}
/**
* Add the <code>zip.plugin</code> target to the given Ant script.
*/
private void generateZipPluginTarget() {
script.println();
script.printTargetDeclaration(TARGET_ZIP_PLUGIN, TARGET_INIT, null, null, NLS.bind(Messages.build_plugin_zipPlugin, model.getSymbolicName()));
script.printDeleteTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), null, null);
script.printMkdirTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER));
script.printAntCallTask(TARGET_BUILD_JARS, true, null);
script.printAntCallTask(TARGET_BUILD_SOURCES, true, null);
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER) + '/');
script.printAntCallTask(TARGET_GATHER_BIN_PARTS, true, params);
script.printAntCallTask(TARGET_GATHER_SOURCES, true, params);
FileSet fileSet = new FileSet(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), null, "**/*.bin" + Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION), null, null, null, null); //$NON-NLS-1$
script.printDeleteTask(null, null, new FileSet[] {fileSet});
script.printZipTask(pluginZipDestination, Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), true, false, null);
script.printDeleteTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), null, null);
script.printTargetEnd();
}
/**
* Add the <code>build.update.jar</code> target to the given Ant script.
*/
private void generateBuildUpdateJarTarget() {
script.println();
script.printTargetDeclaration(TARGET_BUILD_UPDATE_JAR, TARGET_INIT, null, null, NLS.bind(Messages.build_plugin_buildUpdateJar, model.getSymbolicName()));
script.printDeleteTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), null, null);
script.printMkdirTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER));
script.printAntCallTask(TARGET_BUILD_JARS, true, null);
Map<String, String> params = new HashMap<>(1);
params.put(PROPERTY_DESTINATION_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER) + '/');
script.printAntCallTask(TARGET_GATHER_BIN_PARTS, true, params);
script.printJarTask(pluginUpdateJarDestination, Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER) + '/' + fullName, null, "merge"); //$NON-NLS-1$
script.printDeleteTask(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER), null, null);
if (signJars)
script.println("<eclipse.jarProcessor sign=\"" + Utils.getPropertyFormat(PROPERTY_SIGN) + "\" pack=\"" + Utils.getPropertyFormat(PROPERTY_PACK) + "\" unsign=\"" + Utils.getPropertyFormat(PROPERTY_UNSIGN) + "\" jar=\"" + AntScript.getEscaped(pluginUpdateJarDestination) + "\" 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>refresh</code> target to the given Ant script.
*/
private void generateRefreshTarget() {
script.println();
script.printTargetDeclaration(TARGET_REFRESH, TARGET_INIT, PROPERTY_ECLIPSE_RUNNING, null, Messages.build_plugin_refresh);
script.printConvertPathTask(new Path(getLocation(model)).removeLastSegments(0).toOSString().replace('\\', '/'), PROPERTY_RESOURCE_PATH, false);
script.printRefreshLocalTask(Utils.getPropertyFormat(PROPERTY_RESOURCE_PATH), "infinite"); //$NON-NLS-1$
script.printTargetEnd();
}
/**
* End the script by closing the project element.
*/
private void generateEpilogue() {
script.println();
script.printProjectEnd();
}
/**
* Defines, the XML declaration, Ant project and targets init and initTemplate.
* @throws CoreException
*/
private void generatePrologue() throws CoreException {
script.printProjectDeclaration(model.getSymbolicName(), TARGET_BUILD_JARS, DOT);
script.println();
script.printProperty(PROPERTY_P2_BUILD_REPO, "file:" + Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + "/buildRepo"); //$NON-NLS-1$ //$NON-NLS-2$
script.printProperty(PROPERTY_BASE_WS, Utils.getPropertyFormat(PROPERTY_WS));
script.printProperty(PROPERTY_BASE_OS, Utils.getPropertyFormat(PROPERTY_OS));
script.printProperty(PROPERTY_BASE_ARCH, Utils.getPropertyFormat(PROPERTY_ARCH));
script.printProperty(PROPERTY_BASE_NL, Utils.getPropertyFormat(PROPERTY_NL));
script.printProperty(PROPERTY_BUNDLE_ID, model.getSymbolicName());
script.printProperty(PROPERTY_BUNDLE_VERSION, model.getVersion().toString());
script.printProperty(PROPERTY_P2_PUBLISHONERROR, FALSE);
script.println();
if (customBuildCallbacks != null && !customBuildCallbacks.equals(FALSE)) {
script.printAvailableTask(PROPERTY_CUSTOM_BUILD_CALLBACKS, customCallbacksBuildpath + '/' + customBuildCallbacks, customBuildCallbacks);
script.println();
}
generateCompilerSettings();
script.printTargetDeclaration(TARGET_INIT, TARGET_PROPERTIES, null, null, null);
script.printConditionIsSet(PROPERTY_PLUGIN_TEMP, Utils.getPropertyFormat(PROPERTY_BUILD_TEMP) + '/' + DEFAULT_PLUGIN_LOCATION, PROPERTY_BUILD_TEMP);
script.printProperty(PROPERTY_PLUGIN_TEMP, Utils.getPropertyFormat(PROPERTY_BASEDIR));
script.printConditionIsSet(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_PLUGIN_TEMP) + '/' + getNormalizedName(model), PROPERTY_BUILD_TEMP);
script.printProperty(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_BASEDIR));
script.printProperty(PROPERTY_TEMP_FOLDER, Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + PROPERTY_TEMP_FOLDER);
script.printProperty(PROPERTY_PLUGIN_DESTINATION, Utils.getPropertyFormat(PROPERTY_BASEDIR));
script.printConditionIsTrue(PROPERTY_P2_PUBLISH_PARTS, TRUE, Utils.getPropertyFormat(PROPERTY_P2_GATHERING));
script.printProperty(PROPERTY_COMPILE_PROBLEM_MARKER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER) + '/' + "compilation.problem"); //$NON-NLS-1$
script.printConditionStart(PROPERTY_COMPILE_PROBLEM_MARKER_EXISTS, TRUE, null);
script.printStartTag("and"); //$NON-NLS-1$
script.printAvailableTask(null, Utils.getPropertyFormat(PROPERTY_COMPILE_PROBLEM_MARKER));
script.printIsFalse(Utils.getPropertyFormat(PROPERTY_P2_PUBLISHONERROR));
script.printEndTag("and"); //$NON-NLS-1$
script.printEndCondition();
script.printTargetEnd();
script.println();
script.printTargetDeclaration(TARGET_PROPERTIES, null, PROPERTY_ECLIPSE_RUNNING, null, null);
script.printProperty(PROPERTY_BUILD_COMPILER, JDT_COMPILER_ADAPTER);
script.println();
script.printTargetEnd();
}
private void generateCompilerSettings() throws CoreException {
String javacSource = null;
String javacTarget = null;
String bootClasspath = null;
String jreProfile = null;
try {
Properties properties = getBuildProperties();
javacSource = properties.getProperty(IBuildPropertiesConstants.PROPERTY_JAVAC_SOURCE);
javacTarget = properties.getProperty(IBuildPropertiesConstants.PROPERTY_JAVAC_TARGET);
bootClasspath = properties.getProperty(IBuildPropertiesConstants.PROPERTY_BOOT_CLASSPATH);
jreProfile = properties.getProperty(IBuildPropertiesConstants.PROPERTY_JRE_COMPILATION_PROFILE);
} catch (CoreException e) {
//ignore
}
script.printComment(Messages.build_compilerSetting);
script.printProperty(PROPERTY_JAVAC_FAIL_ON_ERROR, "false"); //$NON-NLS-1$
script.printProperty(PROPERTY_JAVAC_DEBUG_INFO, "on"); //$NON-NLS-1$
script.printProperty(PROPERTY_JAVAC_VERBOSE, "false"); //$NON-NLS-1$
script.printProperty(PROPERTY_LOG_EXTENSION, ".log"); //$NON-NLS-1$
script.printProperty(PROPERTY_JAVAC_COMPILERARG, ""); //$NON-NLS-1$
script.printProperty(PROPERTY_PREREQ_COMPILE_LOG, Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + "/prereqErrors.log"); //$NON-NLS-1$
if (javacSource == null)
script.printProperty(IXMLConstants.PROPERTY_JAVAC_SOURCE, "1.3"); //$NON-NLS-1$
if (javacTarget == null)
script.printProperty(IXMLConstants.PROPERTY_JAVAC_TARGET, "1.2"); //$NON-NLS-1$
if (bootClasspath == null) {
script.println("<condition property=\"dir_bootclasspath\" value=\"${java.home}/../Classes\">");//$NON-NLS-1$
script.println("\t<and>"); //$NON-NLS-1$
script.println("\t\t<os family=\"mac\"/>");//$NON-NLS-1$
script.println("\t\t<available file=\"${java.home}/../Classes\" type=\"dir\"/>"); //$NON-NLS-1$
script.println("\t</and>"); //$NON-NLS-1$
script.println("</condition>");//$NON-NLS-1$
script.println("<property name=\"dir_bootclasspath\" value=\"${java.home}/lib\"/>");//$NON-NLS-1$
script.println("<path id=\"path_bootclasspath\">");//$NON-NLS-1$
script.println("\t<fileset dir=\"${dir_bootclasspath}\">");//$NON-NLS-1$
script.println("\t\t<include name=\"*.jar\"/>");//$NON-NLS-1$
script.println("\t</fileset>");//$NON-NLS-1$
script.println("</path>");//$NON-NLS-1$
script.printPropertyRefid(PROPERTY_BOOTCLASSPATH, "path_bootclasspath"); //$NON-NLS-1$
}
Properties environmentMappings = getExecutionEnvironmentMappings();
if (jreProfile != null && !environmentMappings.containsKey(jreProfile + '.' + IXMLConstants.PROPERTY_JAVAC_SOURCE)) {
if (reportResolutionErrors) {
IStatus status = new Status(IStatus.ERROR, model.getSymbolicName(), IStatus.ERROR, NLS.bind(Messages.build_plugin_unrecognizedJRE, jreProfile), null);
BundleHelper.getDefault().getLog().log(status);
}
jreProfile = null;
}
if (javacSource != null)
script.printProperty(PROPERTY_BUNDLE_JAVAC_SOURCE, javacSource);
if (javacTarget != null)
script.printProperty(PROPERTY_BUNDLE_JAVAC_TARGET, javacTarget);
if (bootClasspath != null)
script.printProperty(PROPERTY_BUNDLE_BOOTCLASSPATH, bootClasspath);
String source, target = null;
String[] modelEnvironments = model.getExecutionEnvironments();
String[] environments = null;
if (jreProfile != null) {
environments = new String[modelEnvironments.length + 1];
environments[0] = jreProfile;
System.arraycopy(modelEnvironments, 0, environments, 1, modelEnvironments.length);
} else {
environments = modelEnvironments;
}
ProfileManager profileManager = getSite(false).getRegistry().getProfileManager();
for (int i = 0; i < environments.length; i++) {
if (bootClasspath == null)
script.printConditionIsSet(PROPERTY_BUNDLE_BOOTCLASSPATH, Utils.getPropertyFormat(environments[i]), environments[i]);
source = profileManager.getJavacSource(environments[i]);
if (source == null)
source = (String) environmentMappings.get(environments[i] + '.' + IXMLConstants.PROPERTY_JAVAC_SOURCE);
target = profileManager.getJavacTarget(environments[i]);
if (target == null)
target = (String) environmentMappings.get(environments[i] + '.' + IXMLConstants.PROPERTY_JAVAC_TARGET);
if (javacSource == null && source != null)
script.printConditionIsSet(PROPERTY_BUNDLE_JAVAC_SOURCE, source, environments[i]);
if (javacTarget == null && target != null)
script.printConditionIsSet(PROPERTY_BUNDLE_JAVAC_TARGET, target, environments[i]);
}
if (javacSource == null)
script.printProperty(PROPERTY_BUNDLE_JAVAC_SOURCE, Utils.getPropertyFormat(IXMLConstants.PROPERTY_JAVAC_SOURCE));
if (javacTarget == null)
script.printProperty(PROPERTY_BUNDLE_JAVAC_TARGET, Utils.getPropertyFormat(IXMLConstants.PROPERTY_JAVAC_TARGET));
if (bootClasspath == null)
script.printProperty(PROPERTY_BUNDLE_BOOTCLASSPATH, Utils.getPropertyFormat(PROPERTY_BOOTCLASSPATH));
script.println();
}
/**
* Sets the PluginModel to generate script from.
*
* @param model
* @throws CoreException
*/
public void setModel(BundleDescription model) throws CoreException {
if (model == null) {
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ELEMENT_MISSING, Messages.error_missingElement, null));
}
model = getSite(false).getRegistry().getVersionReplacement(model);
this.model = model;
if (getBuildProperties() == AbstractScriptGenerator.MissingProperties.getInstance()) {
//if there were no build.properties, then it is a binary plugin
binaryPlugin = true;
} else {
getCompiledElements().add(getNormalizedName(model));
}
Properties bundleProperties = (Properties) model.getUserObject();
if (bundleProperties == null) {
bundleProperties = new Properties();
model.setUserObject(bundleProperties);
}
bundleProperties.put(IS_COMPILED, binaryPlugin ? Boolean.FALSE : Boolean.TRUE);
}
/**
* Sets model to generate scripts from.
*
* @param modelId
* @throws CoreException
*/
public void setModelId(String modelId, String modelVersion) throws CoreException {
BundleDescription newModel = getModel(modelId, modelVersion);
if (newModel == null) {
String message = NLS.bind(Messages.exception_missingElement, modelId);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_ELEMENT_MISSING, message, null));
}
setModel(newModel);
}
/**
* 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);
script.printTargetEnd();
}
/**
* Sets the featureGenerator.
* @param featureGenerator The featureGenerator to set
*/
public void setFeatureGenerator(BuildDirector featureGenerator) {
this.featureGenerator = featureGenerator;
}
/**
* Add the "build.jars" target to the given Ant script using the specified plug-in model.
*
* @param pluginModel the plug-in model to reference
* @throws CoreException
*/
private void generateBuildJarsTarget(BundleDescription pluginModel) throws CoreException {
Properties properties = getBuildProperties();
CompiledEntry[] availableJars = extractEntriesToCompile(properties);
compiledJarNames = new ArrayList<>(availableJars.length);
Map<String, CompiledEntry> jars = new HashMap<>(availableJars.length);
for (int i = 0; i < availableJars.length; i++)
jars.put(availableJars[i].getName(false), availableJars[i]);
// Put the jars in a correct compile order
String jarOrder = (String) getBuildProperties().get(PROPERTY_JAR_ORDER);
IClasspathComputer classpath = new ClasspathComputer3_0(this);
if (jarOrder != null) {
String[] order = Utils.getArrayFromString(jarOrder);
for (int i = 0; i < order.length; i++) {
CompiledEntry jar = jars.get(order[i]);
if (jar == null)
continue;
compiledJarNames.add(jar);
generateCompilationTarget(classpath.getClasspath(pluginModel, jar), jar);
generateSRCTarget(jar);
jars.remove(order[i]);
}
}
for (Iterator<CompiledEntry> iterator = jars.values().iterator(); iterator.hasNext();) {
CompiledEntry jar = iterator.next();
compiledJarNames.add(jar);
generateCompilationTarget(classpath.getClasspath(pluginModel, jar), jar);
generateSRCTarget(jar);
}
script.println();
script.printTargetDeclaration(TARGET_BUILD_JARS, TARGET_INIT, null, null, NLS.bind(Messages.build_plugin_buildJars, pluginModel.getSymbolicName()));
script.printDeleteTask(null, Utils.getPropertyFormat(PROPERTY_COMPILE_PROBLEM_MARKER), TRUE, null);
Map<String, String> params = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(1);
params.put(PROPERTY_BUILD_RESULT_FOLDER, Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER));
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_BUILD_JARS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
for (Iterator<CompiledEntry> iter = compiledJarNames.iterator(); iter.hasNext();) {
String name = iter.next().getName(false);
script.printAvailableTask(name, replaceVariables(getJARLocation(name), true));
script.printAntCallTask(name, true, null);
}
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_BUILD_JARS, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
script.println();
generateCheckCompilationTask(pluginModel);
script.printTargetDeclaration(TARGET_BUILD_SOURCES, TARGET_INIT, null, null, null);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + TARGET_BUILD_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
for (Iterator<CompiledEntry> iter = compiledJarNames.iterator(); iter.hasNext();) {
String jarName = iter.next().getName(false);
String srcName = getSRCName(jarName);
script.printAvailableTask(srcName, getSRCLocation(jarName));
script.printAntCallTask(srcName, true, null);
}
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + TARGET_BUILD_SOURCES, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, null);
}
script.printTargetEnd();
}
private void generateCheckCompilationTask(BundleDescription pluginModel) throws CoreException {
script.printTargetDeclaration(TARGET_CHECK_COMPILATION_RESULTS, null, PROPERTY_COMPILATION_ERROR, null, null);
script.printEchoTask(Utils.getPropertyFormat(PROPERTY_COMPILE_PROBLEM_MARKER), getNormalizedName(pluginModel) + "${line.separator}" + PROPERTY_COMPILATION_ERROR + "=" + Utils.getPropertyFormat(PROPERTY_COMPILATION_ERROR)); //$NON-NLS-1$ //$NON-NLS-2$
Map<String, String> arguments = new HashMap<>();
arguments.put("bundle", getNormalizedName(pluginModel)); //$NON-NLS-1$
arguments.put("log", Utils.getPropertyFormat(PROPERTY_PREREQ_COMPILE_LOG)); //$NON-NLS-1$
script.printStartTag("eclipse.logCompileError", arguments); //$NON-NLS-1$
script.incrementIdent();
arguments.clear();
for (Iterator<Object> iter = getPrequisitePaths().iterator(); iter.hasNext();) {
arguments.put("name", iter.next().toString()); //$NON-NLS-1$
script.printElement("include", arguments); //$NON-NLS-1$
}
script.decrementIdent();
script.printEndTag("eclipse.logCompileError"); //$NON-NLS-1$
script.printTargetEnd();
script.println();
}
private List<Object> getPrequisitePaths() throws CoreException {
Properties properties = (Properties) model.getUserObject();
List<Object> results = new ArrayList<>();
if (properties != null) {
String required = properties.getProperty(PROPERTY_REQUIRED_BUNDLE_IDS);
if (required != null) {
State state = getSite(false).getRegistry().getState();
String[] ids = Utils.getArrayFromString(required, ":"); //$NON-NLS-1$
for (int i = 0; i < ids.length; i++) {
try {
BundleDescription bundle = state.getBundle(Long.valueOf(ids[i]).longValue());
if (bundle != null && !Utils.isBinary(bundle)) {
Path bundleLocation = new Path(bundle.getLocation());
results.add(bundleLocation.append("compilation.problem")); //$NON-NLS-1$
results.add(Utils.getPropertyFormat(PROPERTY_PLUGIN_TEMP) + '/' + getNormalizedName(bundle) + "/compilation.problem"); //$NON-NLS-1$
}
} catch (NumberFormatException e) {
//ignore
}
}
}
}
return results;
}
/**
* generate compile settings for compiling this entry
* warning levels, default encoding, custom encodings
* @param javac
* @param entry
*/
private void generateCompilerSettings(JavacTask javac, CompiledEntry entry, List<Object> classpath) {
final String ADAPTER_ENCODING = "#ADAPTER#ENCODING#"; //$NON-NLS-1$
final String ADAPTER_ACCESS = "#ADAPTER#ACCESS#"; //$NON-NLS-1$
Properties properties = null;
try {
properties = getBuildProperties();
} catch (CoreException e) {
return;
}
if (properties == null && classpath.size() == 0)
return;
String name = entry.getName(false);
String excludes = properties.getProperty(PROPERTY_EXCLUDE_PREFIX + name);
if (excludes != null) {
javac.setExcludes(Utils.getArrayFromString(excludes, ",")); //$NON-NLS-1$
}
if (name.equals(EXPANDED_DOT))
name = DOT;
// Bug 303960 potentially use a custom compiler adapter
String compilerAdapter = properties.getProperty(PROPERTY_COMPILER_ADAPTER);
if (compilerAdapter != null) {
javac.setCompilerAdapter(compilerAdapter);
javac.setAdapterUseLog(Boolean.valueOf(properties.getProperty(PROPERTY_ADAPTER_USELOG, TRUE)).booleanValue());
javac.setAdapterArgFile(Boolean.valueOf(properties.getProperty(PROPERTY_ADAPTER_USEARGFILE, TRUE)).booleanValue());
}
// Bug 303960 get compilerArg property
String compilerArg = properties.getProperty(PROPERTY_JAVAC_COMPILERARG);
if (compilerArg != null)
javac.setSpecificCompileArgs(compilerArg);
String defaultEncodingVal = properties.getProperty(PROPERTY_JAVAC_DEFAULT_ENCODING_PREFIX + name);
if (defaultEncodingVal != null)
javac.setEncoding(defaultEncodingVal);
String customEncodingsVal = properties.getProperty(PROPERTY_JAVAC_CUSTOM_ENCODINGS_PREFIX + name);
String warningLevels = properties.getProperty(PROPERTY_JAVAC_WARNINGS_PREFIX + name);
String errorLevels = properties.getProperty(PROPERTY_JAVAC_ERRORS_PREFIX + name);
if (customEncodingsVal == null && warningLevels == null && errorLevels == null && classpath.size() == 0) {
return;
}
String root = getLocation(model);
File file = new File(root, "javaCompiler." + name.replaceAll("[\\\\/]", "_") + ".args"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
if (file.exists()) {
file.delete();
}
Writer writer = null;
try {
try {
//only create the file if we are going to write something in it
if (warningLevels != null || customEncodingsVal != null || errorLevels != null)
writer = new BufferedWriter(new FileWriter(file));
if (warningLevels != null) {
writer.write("-warn:" + warningLevels + "\n"); //$NON-NLS-1$//$NON-NLS-2$
}
if (errorLevels != null) {
writer.write("-err:" + errorLevels + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
}
if (customEncodingsVal != null) {
String[] encodings = customEncodingsVal.split(","); //$NON-NLS-1$
if (encodings.length > 0) {
for (int i = 0; i < encodings.length; i++) {
writer.write(ADAPTER_ENCODING + encodings[i] + "\n"); //$NON-NLS-1$
}
}
}
//handle access rules if we are using ClasspathComputer3_0
Properties data = (Properties) model.getUserObject();
if (data == null || !data.containsKey(PROPERTY_CONVERTED_MANIFEST)) {
if (classpath.size() > 0 && classpath.get(0) instanceof ClasspathElement) {
for (Iterator<Object> iterator = classpath.iterator(); iterator.hasNext();) {
ClasspathElement element = (ClasspathElement) iterator.next();
if (element.getPath() != null && element.getAccessRules().length() > 0) {
String path = null;
if (element.getSubPath() == null)
path = element.getPath();
else
path = featureGenerator.getExtractedRoot(element) + '/' + element.getSubPath();
if (path.startsWith(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER))) {
//remove leading ${build.result.folder}/
path = path.substring(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER).length() + 1);
}
//remove leading ../../..
path = path.replaceFirst("^(\\.\\.[\\\\/])*", ""); //$NON-NLS-1$//$NON-NLS-2$
if (writer == null)
writer = new BufferedWriter(new FileWriter(file));
writer.write(ADAPTER_ACCESS + path + element.getAccessRules() + "\n"); //$NON-NLS-1$
}
}
}
}
if (writer != null)
javac.setCompileArgsFile(Utils.getPropertyFormat(PROPERTY_BASEDIR) + "/" + file.getName()); //$NON-NLS-1$
} finally {
if (writer != null)
writer.close();
}
} catch (IOException e1) {
//ignore
}
}
/**
* Add a target to extract any nested jars we need to compile against
* @param classpath
* @param entry
* @return a new classpath list containing the extracted locations
*/
private List<Object> generateExtractNestedJars(List<Object> classpath, CompiledEntry entry) {
script.printTargetDeclaration(entry.getName(false) + TARGET_NESTED_JARS, null, null, null, null);
if (classpath == null || classpath.size() == 0 || !(classpath.get(0) instanceof ClasspathElement)) {
script.printTargetEnd();
return classpath;
}
List<Object> extracted = new ArrayList<>(classpath.size());
for (Iterator<Object> iterator = classpath.iterator(); iterator.hasNext();) {
ClasspathElement element = (ClasspathElement) iterator.next();
if (element.getSubPath() == null)
extracted.add(element);
else {
String destPath = featureGenerator.getExtractedRoot(element);
String destDir = Utils.getPropertyFormat(PROPERTY_BUILD_DIRECTORY) + '/' + "nestedJars" + '/' + destPath.toString(); //$NON-NLS-1$
script.printMkdirTask(destDir);
script.printUnzipTask(element.getPath(), destDir, false, element.getSubPath(), null);
extracted.add(destDir + '/' + element.getSubPath());
}
}
script.printTargetEnd();
return extracted;
}
/**
* Add the "jar" target to the given Ant script using the given classpath and
* jar as parameters.
*
* @param classpath the classpath for the jar command
* @param entry
*/
private void generateCompilationTarget(List<Object> classpath, CompiledEntry entry) {
script.println();
String name = entry.getName(false);
//extract nested jars and update the classpath with the new locations
List<Object> extractedPath = generateExtractNestedJars(classpath, entry);
String depends = TARGET_INIT + "," + name + TARGET_NESTED_JARS; //$NON-NLS-1$
script.printTargetDeclaration(name, depends, null, entry.getName(true), NLS.bind(Messages.build_plugin_jar, model.getSymbolicName() + ' ' + name));
String destdir = (entry.getType() == CompiledEntry.FOLDER) ? getJARLocation(entry.getName(true)) : getTempJARFolderLocation(entry.getName(true));
script.printDeleteTask(destdir, null, null);
script.printMkdirTask(destdir);
script.printPathStructure("path", name + PROPERTY_CLASSPATH, extractedPath); //$NON-NLS-1$
String[] sources = entry.getSource();
Map<String, String> params = null, references = null;
if (customBuildCallbacks != null) {
params = new HashMap<>(2);
params.put(PROPERTY_TARGET_FOLDER, destdir);
for (int i = 1; i <= sources.length; i++) {
params.put(PROPERTY_SOURCE_FOLDER + i, sources[i - 1]);
}
references = new HashMap<>(1);
references.put(name + PROPERTY_CLASSPATH, null);
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_PRE + name, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, references);
}
FileSet[] workspaceFiles = null;
String outputKey = name.equals(EXPANDED_DOT) ? DOT : name;
if (workspaceOutputFolders != null && workspaceOutputFolders.containsKey(outputKey)) {
// this is a no-op when using p2Gathering on folders GatherBundleTask will collect the class files from where they are.
// unless the class files are in a nested jar, or we are using custom callbacks, then we need to gather everything as before
boolean isFolder = (entry.getType() == CompiledEntry.FOLDER);
if (!BuildDirector.p2Gathering || !isFolder || customBuildCallbacks != null) {
Set<IPath> paths = workspaceOutputFolders.get(outputKey);
workspaceFiles = new FileSet[paths.size()];
int i = 0;
for (Iterator<IPath> iterator = paths.iterator(); iterator.hasNext();) {
IPath path = iterator.next();
workspaceFiles[i++] = new FileSet(Utils.getPropertyFormat(PROPERTY_BASEDIR) + "/" + path.toOSString(), null, null, null, "**/package.htm*", null, null); //$NON-NLS-1$ //$NON-NLS-2$
}
//if entry is a folder, copy over the class files, otherwise they will be jarred from where they are.
if (isFolder) {
script.printCopyTask(null, destdir, workspaceFiles, true, false);
}
}
} else {
script.printComment("compile the source code"); //$NON-NLS-1$
JavacTask javac = new JavacTask();
javac.setClasspathId(name + PROPERTY_CLASSPATH);
String[] executionEnvironments = model.getExecutionEnvironments();
boolean isModular = false;
// 1 execution env associated with the model
if (executionEnvironments.length == 1) {
String ee = executionEnvironments[0];
ProfileManager profileManager = null;
try {
profileManager = getSite(false).getRegistry().getProfileManager();
} catch (CoreException e) {
//nothing to do, will assume non-modular
}
String source = null;
if (profileManager != null)
source = profileManager.getJavacSource(ee);
int parseInt = -1;
try {
parseInt = Integer.parseInt(source);
} catch (NumberFormatException ne) {
//by default non-modular for 1.8 etc and below
}
if (parseInt >= 9)
isModular = true;
}
javac.setBootClasspath(isModular == true ? null : Utils.getPropertyFormat(PROPERTY_BUNDLE_BOOTCLASSPATH));
javac.setDestdir(destdir);
javac.setFailOnError(Utils.getPropertyFormat(PROPERTY_JAVAC_FAIL_ON_ERROR));
javac.setDebug(Utils.getPropertyFormat(PROPERTY_JAVAC_DEBUG_INFO));
javac.setVerbose(Utils.getPropertyFormat(PROPERTY_JAVAC_VERBOSE));
javac.setIncludeAntRuntime("no"); //$NON-NLS-1$
javac.setSource(Utils.getPropertyFormat(PROPERTY_BUNDLE_JAVAC_SOURCE));
javac.setTarget(Utils.getPropertyFormat(PROPERTY_BUNDLE_JAVAC_TARGET));
javac.setCompileArgs(Utils.getPropertyFormat(PROPERTY_JAVAC_COMPILERARG));
javac.setSrcdir(sources);
javac.setLogExtension(Utils.getPropertyFormat(PROPERTY_LOG_EXTENSION));
if (warningProperties != null)
javac.setWarningProperties(Utils.getPropertyFormat(PROPERTY_BASEDIR) + '/' + warningProperties);
if (generateErrorPropertyAttribute)
javac.setErrorProperty(PROPERTY_COMPILATION_ERROR);
generateCompilerSettings(javac, entry, classpath);
script.print(javac);
}
script.printAntCallTask(TARGET_CHECK_COMPILATION_RESULTS, true, null);
script.printComment("Copy necessary resources"); //$NON-NLS-1$
FileSet[] fileSets = new FileSet[sources.length];
for (int i = 0; i < sources.length; i++) {
String excludes = getFormattedSourceFileExtensions();
if (excludes.length() > 0) {
excludes += ", **/package.htm*"; //$NON-NLS-1$
} else {
excludes = "**/package.htm*"; //$NON-NLS-1$
}
String excludedFromJar = entry.getExcludedFromJar();
if (excludedFromJar != null)
excludes += ',' + excludedFromJar;
fileSets[i] = new FileSet(sources[i], null, null, null, excludes, null, null);
}
script.printCopyTask(null, destdir, fileSets, true, false);
if (customBuildCallbacks != null) {
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST_COMPILE + name, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, references);
}
String jarLocation = getJARLocation(entry.getName(true));
if (entry.getType() != CompiledEntry.FOLDER) {
script.printMkdirTask(new Path(jarLocation).removeLastSegments(1).toString());
if (workspaceFiles != null)
script.printJarTask(jarLocation, destdir, workspaceFiles, getEmbeddedManifestFile(entry, destdir), null, "preserve"); //$NON-NLS-1$
else
script.printJarTask(jarLocation, destdir, getEmbeddedManifestFile(entry, destdir));
script.printDeleteTask(destdir, null, null);
}
if (customBuildCallbacks != null) {
params.clear();
params.put(PROPERTY_JAR_LOCATION, jarLocation);
script.printSubantTask(Utils.getPropertyFormat(PROPERTY_CUSTOM_BUILD_CALLBACKS), PROPERTY_POST + name, customCallbacksBuildpath, customCallbacksFailOnError, customCallbacksInheritAll, params, references);
}
script.printTargetEnd();
}
/*
* The "errorProperty" attribute on the javac task requires ant 1.7.1 or greater
*/
private boolean shouldGenerateErrorAttribute() {
//When exporting from the UI it is hard to know the ant version, for now don't generate the attribute
if (havePDEUIState())
return false;
//version string should look something like: "Apache Ant version 1.7.1 compiled on June 27 2008"
String versionString = getImmutableAntProperty(IBuildPropertiesConstants.PROPERTY_ANT_VERSION);
if (versionString != null) {
int idx = versionString.indexOf("version"); //$NON-NLS-1$
if (idx > 0) {
versionString = versionString.substring(idx + 7).trim();
idx = 0;
int segment = 0;
//try and be flexible, find the first 3 segments of numbers, stop at any other character
for (char c = versionString.charAt(idx); idx < versionString.length() && segment < 3; c = versionString.charAt(++idx)) {
if (c == '.')
segment++;
else if (!Character.isDigit(c))
break;
}
if (idx > 0) {
try {
Version antVersion = new Version(versionString.substring(0, idx));
if (antVersion.compareTo(new Version(1, 7, 1)) >= 0)
return true;
IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, WARNING_OLD_ANT, NLS.bind(Messages.warning_ant171Required, PROPERTY_P2_PUBLISHONERROR), null);
BundleHelper.getDefault().getLog().log(status);
return false;
} catch (IllegalArgumentException e) {
// shouldn't really happen, but catch just in case
}
}
}
}
//we don't know a version, assume someone knew what they were doing with their setup.
return true;
}
private String getEmbeddedManifestFile(CompiledEntry jarEntry, String destdir) {
try {
String manifestName = getBuildProperties().getProperty(PROPERTY_MANIFEST_PREFIX + jarEntry.getName(true));
if (manifestName == null)
return null;
return destdir + '/' + manifestName;
} catch (CoreException e) {
return null;
}
}
/**
*
* @param properties
* @return JAR[]
*/
protected CompiledEntry[] extractEntriesToCompile(Properties properties) throws CoreException {
return extractEntriesToCompile(properties, model);
}
public static CompiledEntry[] extractEntriesToCompile(Properties properties, BundleDescription model) throws CoreException {
List<CompiledEntry> result = new ArrayList<>(5);
int prefixLength = PROPERTY_SOURCE_PREFIX.length();
for (Iterator<Entry<Object, Object>> iterator = properties.entrySet().iterator(); iterator.hasNext();) {
Map.Entry<Object, Object> entry = iterator.next();
String key = (String) entry.getKey();
if (!(key.startsWith(PROPERTY_SOURCE_PREFIX)))
continue;
key = key.substring(prefixLength);
String[] source = Utils.getArrayFromString((String) entry.getValue());
if (source.length == 0) {
String message = NLS.bind(Messages.error_missingSourceFolder, model.getSymbolicName(), entry.getKey());
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_GENERIC, message, null));
}
String[] output = Utils.getArrayFromString(properties.getProperty(PROPERTY_OUTPUT_PREFIX + key));
String[] extraClasspath = Utils.getArrayFromString(properties.getProperty(PROPERTY_EXTRAPATH_PREFIX + key));
String excludedFromJar = properties.getProperty(PROPERTY_EXCLUDE_PREFIX + key);
CompiledEntry newEntry = new CompiledEntry(key, source, output, extraClasspath, excludedFromJar, key.endsWith(PROPERTY_JAR_SUFFIX) ? CompiledEntry.JAR : CompiledEntry.FOLDER);
result.add(newEntry);
}
return result.toArray(new CompiledEntry[result.size()]);
}
/**
* Add the "src" target to the given Ant script.
*
* @param jar
*/
private void generateSRCTarget(CompiledEntry jar) {
script.println();
String name = jar.getName(false);
String srcName = getSRCName(name);
script.printTargetDeclaration(srcName, TARGET_INIT, null, srcName, null);
String[] sources = jar.getSource();
filterNonExistingSourceFolders(sources);
FileSet[] fileSets = new FileSet[sources.length];
int count = 0;
for (int i = 0; i < sources.length; i++) {
if (sources[i] != null)
fileSets[count++] = new FileSet(sources[i], null, getFormattedSourceFileExtensions(), null, null, null, null);
}
String srcLocation = getSRCLocation(name);
String srcParent = new Path(srcLocation).removeLastSegments(1).toString();
script.printMkdirTask(srcParent);
script.printAntCallTask("zip." + srcName, true, null); //$NON-NLS-1$
script.printTargetEnd();
script.printTargetDeclaration("zip." + srcName, null, null, null, null); //$NON-NLS-1$
if (count != 0)
script.printZipTask(srcLocation, null, false, false, fileSets);
script.printTargetEnd();
script.printTargetDeclaration("copy." + srcName, null, null, null, null); //$NON-NLS-1$
if (count != 0) {
String dest = null;
if (srcName.equals(SRC_ZIP))
dest = new Path(srcName).removeLastSegments(1).toString(); //src.zip can go in the root
else
dest = srcName.substring(0, srcName.length() - 4); //remove .zip, the rest go in folders
String toDir = Utils.getPropertyFormat(PROPERTY_SOURCE_DESTINATION_FOLDER) + '/' + dest;
script.printCopyTask(null, toDir, fileSets, true, true);
}
script.printTargetEnd();
}
/**
* @return list of source extensions recognized by the bundle
*/
private String getFormattedSourceFileExtensions() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < sourceFileExtensions.length; i++) {
if (i > 0) {
sb.append(", "); //$NON-NLS-1$
}
sb.append("**/").append(sourceFileExtensions[i]); //$NON-NLS-1$
}
return sb.toString();
}
private void filterNonExistingSourceFolders(String[] sources) {
File pluginRoot;
pluginRoot = new File(getLocation(model));
for (int i = 0; i < sources.length; i++) {
File file = new File(pluginRoot, sources[i]);
if (!file.exists()) {
sources[i] = null;
IStatus status = new Status(IStatus.WARNING, PI_PDEBUILD, EXCEPTION_SOURCE_LOCATION_MISSING, NLS.bind(Messages.warning_cannotLocateSource, file.getAbsolutePath()), null);
BundleHelper.getDefault().getLog().log(status);
}
}
}
/**
* Return the name of the zip file for the source for the jar with
* the given name.
*
* @param jarName the name of the jar file
* @return String
*/
protected String getSRCLocation(String jarName) {
return getJARLocation(getSRCName(jarName));
}
/**
* Return the location for a temporary file for the jar file with
* the given name.
*
* @param jarName the name of the jar file
* @return String
*/
protected String getTempJARFolderLocation(String jarName) {
IPath destination = new Path(Utils.getPropertyFormat(PROPERTY_TEMP_FOLDER));
destination = destination.append(jarName + ".bin"); //$NON-NLS-1$
return destination.toString();
}
/**
* Return the full location of the jar file.
*
* @param jarName the name of the jar file
* @return String
*/
protected String getJARLocation(String jarName) {
return new Path(Utils.getPropertyFormat(PROPERTY_BUILD_RESULT_FOLDER)).append(jarName).toString();
}
protected String[] getClasspathEntries(BundleDescription lookedUpModel) throws CoreException {
return getSite(false).getRegistry().getExtraData().get(Long.valueOf(lookedUpModel.getBundleId()));
}
@Override
protected Properties getBuildProperties() throws CoreException {
if (buildProperties == null)
return buildProperties = readProperties(model.getLocation(), propertiesFileName, isIgnoreMissingPropertiesFile() ? IStatus.OK : IStatus.WARNING);
return buildProperties;
}
/**
* Return the name of the zip file for the source from the given jar name.
*
* @param jarName the name of the jar file
* @return String
*/
public static String getSRCName(String jarName) {
if (jarName.endsWith(".jar")) { //$NON-NLS-1$
return jarName.substring(0, jarName.length() - 4) + SRC_ZIP;
}
if (jarName.equals(EXPANDED_DOT) || jarName.equals(DOT))
return SRC_ZIP;
return jarName.replace('/', '.') + SRC_ZIP;
}
/**
* If the model defines its own custom script, we do not generate a new one
* but we do try to update the version number.
*/
private void updateExistingScript() throws CoreException {
String root = getLocation(model);
File buildFile = new File(root, buildScriptFileName);
if (!buildFile.exists()) {
String message = NLS.bind(Messages.error_missingCustomBuildFile, buildFile);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, null));
}
try {
Utils.updateVersion(buildFile, PROPERTY_VERSION_SUFFIX, model.getVersion().toString());
} catch (IOException e) {
String message = NLS.bind(Messages.exception_writeScript, buildFile);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_SCRIPT, message, e));
}
return;
}
/**
* Substitute the value of an element description variable (variables that
* are found in files like plugin.xml, e.g. $ws$) by an Ant property.
*
* @param sourceString
* @return String
*/
static protected String replaceVariables(String sourceString, boolean compiledElement) {
if (sourceString == null)
return null;
int i = -1;
String result = sourceString;
while ((i = result.indexOf(DESCRIPTION_VARIABLE_WS)) >= 0)
result = result.substring(0, i) + "ws/" + Utils.getPropertyFormat(compiledElement ? PROPERTY_WS : PROPERTY_BASE_WS) + result.substring(i + DESCRIPTION_VARIABLE_WS.length()); //$NON-NLS-1$
while ((i = result.indexOf(DESCRIPTION_VARIABLE_OS)) >= 0)
result = result.substring(0, i) + "os/" + Utils.getPropertyFormat(compiledElement ? PROPERTY_OS : PROPERTY_BASE_OS) + result.substring(i + DESCRIPTION_VARIABLE_OS.length()); //$NON-NLS-1$
while ((i = result.indexOf(DESCRIPTION_VARIABLE_ARCH)) >= 0)
result = result.substring(0, i) + "arch/" + Utils.getPropertyFormat(compiledElement ? PROPERTY_ARCH : PROPERTY_BASE_ARCH) + result.substring(i + DESCRIPTION_VARIABLE_OS.length()); //$NON-NLS-1$
while ((i = result.indexOf(DESCRIPTION_VARIABLE_NL)) >= 0)
result = result.substring(0, i) + "nl/" + Utils.getPropertyFormat(compiledElement ? PROPERTY_NL : PROPERTY_BASE_NL) + result.substring(i + DESCRIPTION_VARIABLE_NL.length()); //$NON-NLS-1$
return result;
}
public BundleDescription getModel() {
return model;
}
public String getPropertiesFileName() {
return propertiesFileName;
}
public void setPropertiesFileName(String propertyFileName) {
this.propertiesFileName = propertyFileName;
}
public String getBuildScriptFileName() {
return buildScriptFileName;
}
public void setBuildScriptFileName(String buildScriptFileName) {
this.buildScriptFileName = buildScriptFileName;
}
/**
* Sets whether or not to sign any constructed jars.
*
* @param value whether or not to sign any constructed JARs
*/
public void setSignJars(boolean value) {
signJars = value;
}
/**
* Returns the model object which is associated with the given identifier.
* Returns <code>null</code> if the model object cannot be found.
*
* @param modelId the identifier of the model object to lookup
* @return the model object or <code>null</code>
*/
protected BundleDescription getModel(String modelId, String modelVersion) throws CoreException {
if (modelVersion == null)
return getSite(false).getRegistry().getResolvedBundle(modelId);
return getSite(false).getRegistry().getResolvedBundle(modelId, modelVersion);
}
public FeatureEntry getAssociatedEntry() {
return associatedEntry;
}
public void setAssociatedEntry(FeatureEntry associatedEntry) {
this.associatedEntry = associatedEntry;
}
protected void setWorkspaceOutputFolders(Map<String, Set<IPath>> folders) {
this.workspaceOutputFolders = folders;
}
public void setGenerateSourceReferences(boolean sourceReferences) {
this.sourceReferences = sourceReferences;
}
}