blob: d0ab963cb3b7a1f678c89c118d69e7611c6ec15b [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
*******************************************************************************/
package org.eclipse.pde.internal.build;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.engine.SimpleProfileRegistry;
import org.eclipse.equinox.internal.p2.publisher.eclipse.ProductFile;
import org.eclipse.equinox.p2.core.IAgentLocation;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.IProfile;
import org.eclipse.equinox.p2.engine.IProfileRegistry;
import org.eclipse.equinox.p2.publisher.eclipse.FeatureEntry;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.osgi.service.resolver.State;
import org.eclipse.osgi.util.NLS;
import org.eclipse.pde.internal.build.ant.AntScript;
import org.eclipse.pde.internal.build.builder.BuildDirector;
import org.eclipse.pde.internal.build.site.*;
import org.eclipse.pde.internal.build.site.compatibility.SiteManager;
import org.osgi.framework.Version;
/**
* Generic super-class for all script generator classes.
* It contains basic informations like the script, the configurations, and a location
*/
public abstract class AbstractScriptGenerator implements IXMLConstants, IPDEBuildConstants, IBuildPropertiesConstants {
private static final FilenameFilter METADATA_REPO_FILTER = (dir, name) -> name.startsWith("content.") || name.startsWith("compositeContent.") || //$NON-NLS-1$ //$NON-NLS-2$
name.endsWith(".profile") || name.endsWith(".profile.gz"); //$NON-NLS-1$//$NON-NLS-2$
private static final FilenameFilter ARTIFACT_REPO_FILTER = (dir, name) -> name.startsWith("artifacts.") || name.startsWith("compositeArtifacts."); //$NON-NLS-1$ //$NON-NLS-2$
private static Properties immutableAntProperties = null;
protected static boolean embeddedSource = false;
protected static boolean forceUpdateJarFormat = false;
private static List<Config> configInfos;
protected static String workingDirectory;
protected URI[] contextMetadata = null;
protected URI[] contextArtifacts = null;
protected AntScript script;
protected Properties platformProperties;
protected String productQualifier;
private static PDEUIStateWrapper pdeUIState;
/** Location of the plug-ins and fragments. */
protected String[] sitePaths;
protected String[] pluginPath;
protected BuildTimeSiteFactory siteFactory;
/**
* Indicate whether the content of the pdestate should only contain the plugins that are in the transitive closure of the features being built
*/
protected boolean filterState = false;
protected List<String> featuresForFilterRoots = new ArrayList<>();
protected List<String> pluginsForFilterRoots = new ArrayList<>();
protected boolean filterP2Base = false;
protected boolean reportResolutionErrors;
static {
// By default, a generic configuration is set
configInfos = new ArrayList<>(1);
configInfos.add(Config.genericConfig());
}
public static List<Config> getConfigInfos() {
return configInfos;
}
/**
* Starting point for script generation. See subclass implementations for
* individual comments.
*
* @throws CoreException
*/
public abstract void generate() throws CoreException;
protected static void setStaticAntProperties(Properties properties) {
if (properties == null) {
immutableAntProperties = new Properties();
BuildDirector.p2Gathering = false;
} else
immutableAntProperties = properties;
if (getImmutableAntProperty(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE) == null) {
immutableAntProperties.setProperty(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE, "false"); //$NON-NLS-1$
}
//When we are generating build scripts, the normalization needs to be set, and when doing packaging the default is to set normalization to true for backward compatibility
if (!getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE) || getImmutableAntProperty(IBuildPropertiesConstants.PROPERTY_PACKAGER_AS_NORMALIZER) == null) {
immutableAntProperties.setProperty(IBuildPropertiesConstants.PROPERTY_PACKAGER_AS_NORMALIZER, "true"); //$NON-NLS-1$
}
if (getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_P2_GATHERING))
BuildDirector.p2Gathering = true;
}
public static String getImmutableAntProperty(String key) {
return getImmutableAntProperty(key, null);
}
public static boolean getPropertyAsBoolean(String key) {
String booleanValue = getImmutableAntProperty(key, null);
if ("true".equalsIgnoreCase(booleanValue)) //$NON-NLS-1$
return true;
return false;
}
public static String getImmutableAntProperty(String key, String defaultValue) {
if (immutableAntProperties == null || !immutableAntProperties.containsKey(key))
return defaultValue;
Object obj = immutableAntProperties.get(key);
return (obj instanceof String) ? (String) obj : null;
}
public static void setConfigInfo(String spec) throws CoreException {
String[] configs = Utils.getArrayFromStringWithBlank(spec, "&"); //$NON-NLS-1$
List<Config> infos = new ArrayList<>(configs.length);
String[] os = new String[configs.length];
String[] ws = new String[configs.length];
String[] archs = new String[configs.length];
for (int i = 0; i < configs.length; i++) {
String[] configElements = Utils.getArrayFromStringWithBlank(configs[i], ","); //$NON-NLS-1$
if (configElements.length != 3) {
IStatus error = new Status(IStatus.ERROR, IPDEBuildConstants.PI_PDEBUILD, IPDEBuildConstants.EXCEPTION_CONFIG_FORMAT, NLS.bind(Messages.error_configWrongFormat, configs[i]), null);
throw new CoreException(error);
}
Config aConfig = new Config(configs[i]);
if (aConfig.equals(Config.genericConfig())) {
infos.add(Config.genericConfig());
} else {
infos.add(aConfig);
}
// create a list of all ws, os and arch to feed the SiteManager
os[i] = aConfig.getOs();
ws[i] = aConfig.getWs();
archs[i] = aConfig.getArch();
}
SiteManager.setOS(Utils.getStringFromArray(os, ",")); //$NON-NLS-1$
SiteManager.setWS(Utils.getStringFromArray(ws, ",")); //$NON-NLS-1$
SiteManager.setArch(Utils.getStringFromArray(archs, ",")); //$NON-NLS-1$
configInfos = infos;
}
public void setWorkingDirectory(String location) {
workingDirectory = location;
}
/**
* Return the file system location for the given plug-in model object.
*
* @param model the plug-in
* @return String
*/
public String getLocation(BundleDescription model) {
return model.getLocation();
}
static public class MissingProperties extends Properties {
private static final long serialVersionUID = 3546924667060303927L;
private static MissingProperties singleton;
private MissingProperties() {
//nothing to do;
}
@Override
public synchronized Object setProperty(String key, String value) {
throw new UnsupportedOperationException();
}
@Override
public synchronized Object put(Object key, Object value) {
throw new UnsupportedOperationException();
}
public static MissingProperties getInstance() {
if (singleton == null)
singleton = new MissingProperties();
return singleton;
}
}
public static Properties readProperties(String location, String fileName, int errorLevel) throws CoreException {
if (location == null) {
if (errorLevel != IStatus.INFO && errorLevel != IStatus.OK) {
String message = NLS.bind(Messages.exception_missingFile, fileName);
BundleHelper.getDefault().getLog().log(new Status(errorLevel, PI_PDEBUILD, EXCEPTION_READING_FILE, message, null));
}
return MissingProperties.getInstance();
}
Properties result = new Properties();
File file = new File(location, fileName);
try (InputStream input = new BufferedInputStream(new FileInputStream(file))) {
result.load(input);
} catch (FileNotFoundException e) {
if (errorLevel != IStatus.INFO && errorLevel != IStatus.OK) {
String message = NLS.bind(Messages.exception_missingFile, file);
BundleHelper.getDefault().getLog().log(new Status(errorLevel, PI_PDEBUILD, EXCEPTION_READING_FILE, message, null));
}
result = MissingProperties.getInstance();
} catch (IOException e) {
String message = NLS.bind(Messages.exception_readingFile, file);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e));
}
return result;
}
public void openScript(String scriptLocation, String scriptName) throws CoreException {
if (script != null)
return;
script = newAntScript(scriptLocation, scriptName);
}
protected static AntScript newAntScript(String scriptLocation, String scriptName) throws CoreException {
AntScript result = null;
try {
OutputStream scriptStream = new BufferedOutputStream(new FileOutputStream(scriptLocation + '/' + scriptName));
try {
result = new AntScript(scriptStream);
} catch (IOException e) {
try {
scriptStream.close();
String message = NLS.bind(Messages.exception_writingFile, scriptLocation + '/' + scriptName);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
} catch (IOException e1) {
// Ignored
}
}
} catch (FileNotFoundException e) {
String message = NLS.bind(Messages.exception_writingFile, scriptLocation + '/' + scriptName);
throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_WRITING_FILE, message, e));
}
return result;
}
public void closeScript() {
script.close();
}
public static String getWorkingDirectory() {
return workingDirectory;
}
public static String getDefaultOutputFormat() {
return "zip"; //$NON-NLS-1$
}
public static boolean getDefaultEmbeddedSource() {
return false;
}
public static void setEmbeddedSource(boolean embed) {
embeddedSource = embed;
}
public static boolean getForceUpdateJarFormat() {
return false;
}
public static void setForceUpdateJar(boolean force) {
forceUpdateJarFormat = force;
}
public static String getDefaultConfigInfos() {
return "*, *, *"; //$NON-NLS-1$
}
protected static boolean loadP2Class() {
try {
BundleHelper.getDefault().getClass().getClassLoader().loadClass("org.eclipse.equinox.p2.publisher.Publisher"); //$NON-NLS-1$
return true;
} catch (Throwable e) {
return false;
}
}
/**
* Return a build time site referencing things to be built.
* @param refresh : indicate if a refresh must be performed. Although this flag is set to true, a new site is not rebuild if the urls of the site did not changed
* @return BuildTimeSite
* @throws CoreException
*/
public BuildTimeSite getSite(boolean refresh) throws CoreException {
if (siteFactory != null && refresh == false)
return siteFactory.createSite();
//If there is an exception from createSite(), we will discard the factory
BuildTimeSiteFactory factory = new BuildTimeSiteFactory();
factory.setFilterState(filterState);
factory.setFilterRoots(featuresForFilterRoots, pluginsForFilterRoots);
factory.setReportResolutionErrors(reportResolutionErrors);
factory.setFilterP2Base(filterP2Base);
factory.setSitePaths(getPaths());
factory.setEESources(getEESources());
factory.setInitialState(pdeUIState);
BuildTimeSite result = factory.createSite();
siteFactory = factory;
if (platformProperties != null)
result.setPlatformPropeties(platformProperties);
File baseProfile = result.getSiteContentProvider().getBaseProfile();
if (baseProfile != null) {
List<URI> repos = getAssociatedRepositories(baseProfile);
if (repos.size() > 0) {
addContextRepos(repos.toArray(new URI[repos.size()]));
}
}
return result;
}
/**
* Method getPaths. These are the paths used for the BuildTimeSite
* @return URL[]
*/
private String[] getPaths() {
if (sitePaths == null) {
if (pluginPath != null) {
sitePaths = new String[pluginPath.length + 1];
System.arraycopy(pluginPath, 0, sitePaths, 0, pluginPath.length);
sitePaths[sitePaths.length - 1] = workingDirectory;
} else {
sitePaths = new String[] {workingDirectory};
}
}
return sitePaths;
}
protected String[] getEESources() {
return null;
}
public void setBuildSiteFactory(BuildTimeSiteFactory siteFactory) {
this.siteFactory = siteFactory;
}
/**
* Return the path of the plugins //TODO Do we need to add support for features, or do we simply consider one list of URL? It is just a matter of style/
* @return URL[]
*/
public String[] getPluginPath() {
return pluginPath;
}
/**
* Sets the pluginPath.
*
* @param path
*/
public void setPluginPath(String[] path) {
pluginPath = path;
}
public void setPDEState(State state) {
ensurePDEUIStateNotNull();
pdeUIState.setState(state);
}
public void setStateExtraData(HashMap<Long, String[]> classpath, Map<Long, String> patchData) {
setStateExtraData(classpath, patchData, null);
}
public void setStateExtraData(HashMap<Long, String[]> classpath, Map<Long, String> patchData, Map<String, Map<String, Set<IPath>>> outputFolders) {
ensurePDEUIStateNotNull();
pdeUIState.setExtraData(classpath, patchData, outputFolders);
}
public void setNextId(long nextId) {
ensurePDEUIStateNotNull();
pdeUIState.setNextId(nextId);
}
protected void flushState() {
pdeUIState = null;
}
private void ensurePDEUIStateNotNull() {
if (pdeUIState == null)
pdeUIState = new PDEUIStateWrapper();
}
protected boolean havePDEUIState() {
return pdeUIState != null;
}
public ProductFile loadProduct(String product) throws CoreException {
//the ProductFile uses the OS to determine which icons to return, we don't care so can use null
//this is better since this generator may be used for multiple OS's
return loadProduct(product, null);
}
public ProductFile loadProduct(String product, String os) throws CoreException {
if (product == null || product.startsWith("${") || product.length() == 0) { //$NON-NLS-1$
return null;
}
String productPath = findFile(product, false);
File f = null;
if (productPath != null) {
f = new File(productPath);
} else {
// couldn't find productFile, try it as a path directly
f = new File(product);
if (!f.exists() || !f.isFile()) {
// doesn't exist, try it as a path relative to the working directory
f = new File(getWorkingDirectory(), product);
if (!f.exists() || !f.isFile()) {
f = new File(getWorkingDirectory() + "/" + DEFAULT_PLUGIN_LOCATION, product); //$NON-NLS-1$
if (!f.exists() || !f.isFile()) {
f = new File(getWorkingDirectory() + '/' + DEFAULT_FEATURE_LOCATION, product);
}
}
}
}
return new ProductFile(f.getAbsolutePath(), os);
}
//Find a file in a bundle or a feature.
//location is assumed to be structured like : /<featureId | pluginId>/path.to.the.file
protected String findFile(String location, boolean makeRelative) {
if (location == null || location.length() == 0)
return null;
//shortcut building the site if we don't need to
if (new File(location).exists())
return location;
PDEState state;
try {
state = getSite(false).getRegistry();
} catch (CoreException e) {
BundleHelper.getDefault().getLog().log(e.getStatus());
return null;
}
Path path = new Path(location);
String id = path.segment(0);
BundleDescription[] matches = state.getState().getBundles(id);
if (matches != null && matches.length != 0) {
BundleDescription bundle = matches[0];
if (bundle != null) {
String result = checkFile(new Path(bundle.getLocation()), path, makeRelative);
if (result != null)
return result;
}
}
// Couldn't find the file in any of the plugins, try in a feature.
BuildTimeFeature feature = null;
try {
feature = getSite(false).findFeature(id, null, false);
} catch (CoreException e) {
BundleHelper.getDefault().getLog().log(e.getStatus());
}
if (feature == null)
return null;
String featureRoot = feature.getRootLocation();
if (featureRoot != null)
return checkFile(new Path(featureRoot), path, makeRelative);
return null;
}
protected String findConfigFile(ProductFile productFile, String os) {
String path = productFile.getConfigIniPath(os);
if (path == null)
return null;
String result = findFile(path, false);
if (result != null)
return result;
// couldn't find productFile, try it as a path directly
File f = new File(path);
if (f.exists() && f.isFile())
return f.getAbsolutePath();
// relative to the working directory
f = new File(getWorkingDirectory(), path);
if (f.exists() && f.isFile())
return f.getAbsolutePath();
// relative to the working directory/plugins
f = new File(getWorkingDirectory() + "/" + DEFAULT_PLUGIN_LOCATION, path); //$NON-NLS-1$
if (f.exists() && f.isFile())
return f.getAbsolutePath();
//relative to .product file
f = new File(productFile.getLocation().getParent(), path);
if (f.exists() && f.isFile())
return f.getAbsolutePath();
return null;
}
private String checkFile(IPath base, Path target, boolean makeRelative) {
IPath path = base.append(target.removeFirstSegments(1));
String result = path.toOSString();
if (!new File(result).exists())
return null;
if (makeRelative)
return Utils.makeRelative(path, new Path(workingDirectory)).toOSString();
return result;
}
public void setFilterState(boolean filter) {
filterState = filter;
}
public void setFilterP2Base(boolean filter) {
filterP2Base = filter;
}
static private URI getDownloadCacheLocation(IProvisioningAgent agent) {
IAgentLocation location = (IAgentLocation) agent.getService(IAgentLocation.SERVICE_NAME);
if (location == null)
return null;
return URIUtil.append(location.getDataArea("org.eclipse.equinox.p2.core"), "cache/"); //$NON-NLS-1$ //$NON-NLS-2$
}
protected void setContextArtifacts(URI[] uris) {
contextArtifacts = uris;
}
protected void setContextMetadata(URI[] uris) {
contextMetadata = uris;
}
public void setContextMetadataRepositories(URI[] uris) {
Set<URI> uriSet = new HashSet<>();
uriSet.addAll(Arrays.asList(uris));
for (int i = 0; i < uris.length; i++) {
//try and find additional repos associated with a profile
File uriFile = URIUtil.toFile(uris[i]);
uriSet.addAll(getAssociatedRepositories(uriFile));
}
addContextRepos(uriSet.toArray(new URI[uriSet.size()]));
}
protected void addContextRepos(URI[] repos) {
List<URI> metadata = filterRepos(repos, METADATA_REPO_FILTER);
List<URI> artifacts = filterRepos(repos, ARTIFACT_REPO_FILTER);
if (contextMetadata != null) {
Set<URI> uriSet = new HashSet<>();
uriSet.addAll(Arrays.asList(contextMetadata));
uriSet.addAll(metadata);
contextMetadata = uriSet.toArray(new URI[uriSet.size()]);
} else {
contextMetadata = metadata.toArray(new URI[metadata.size()]);
}
if (contextArtifacts != null) {
Set<URI> uriSet = new HashSet<>();
uriSet.addAll(Arrays.asList(contextArtifacts));
uriSet.addAll(artifacts);
contextArtifacts = uriSet.toArray(new URI[uriSet.size()]);
} else {
contextArtifacts = artifacts.toArray(new URI[artifacts.size()]);
}
}
//return only the metadata repos, and also the ones we aren't sure about
private List<URI> filterRepos(URI[] contexts, FilenameFilter repoFilter) {
if (contexts == null)
return null;
ArrayList<URI> result = new ArrayList<>();
for (int i = 0; i < contexts.length; i++) {
File repo = URIUtil.toFile(contexts[i]);
if (repo == null) {
//remote, not sure, just use it
result.add(contexts[i]);
} else {
String[] list = repo.list(repoFilter);
if (list != null && list.length > 0)
result.add(contexts[i]);
}
}
return result;
}
private List<URI> getAssociatedRepositories(File profileFile) {
if (profileFile == null || !profileFile.exists() || !profileFile.getName().endsWith(".profile")) //$NON-NLS-1$
return Collections.emptyList();
ArrayList<URI> result = new ArrayList<>();
URI profileURI = profileFile.toURI();
result.add(profileURI);
Map<String, Object> profileInfo = extractProfileInformation(profileFile);
if (profileInfo == null)
return result;
File areaFile = new File((String) profileInfo.get(PROFILE_DATA_AREA));
if (areaFile.exists()) {
IProvisioningAgent agent = BundleHelper.getDefault().getProvisioningAgent(areaFile.toURI());
if (agent != null) {
IProfileRegistry registry = new SimpleProfileRegistry(agent, (File) profileInfo.get(PROFILE_REGISTRY), null, false);
try {
long timestamp = ((Long) profileInfo.get(PROFILE_TIMESTAMP)).longValue();
String profileId = (String) profileInfo.get(PROFILE_ID);
if (timestamp == -1L) {
long[] timestamps = registry.listProfileTimestamps(profileId);
if (timestamps.length > 0)
timestamp = timestamps[timestamps.length - 1];
}
//specifying the timestamp avoids attempting to lock the profile registry
//which could be a problem if it is read only.
if (timestamp > 0) {
IProfile profile = registry.getProfile(profileId, timestamp);
if (profile != null) {
String cache = profile.getProperty(IProfile.PROP_CACHE);
if (cache != null) {
File cacheFolder = new File(cache);
if (cacheFolder.exists()) {
result.add(cacheFolder.toURI());
} else {
//if cache does not exist, this could be a roaming profile that has not
//been run yet, lets guess and use the parent of the p2 data area
result.add(areaFile.getParentFile().toURI());
}
}
String sharedCache = profile.getProperty(IProfile.PROP_SHARED_CACHE);
if (sharedCache != null)
result.add(new File(cache).toURI());
String dropinRepositories = profile.getProperty("org.eclipse.equinox.p2.cache.extensions"); //$NON-NLS-1$
if (dropinRepositories != null) {
// #filterRepos will remove any dropin folders that require synchronization
StringTokenizer tokenizer = new StringTokenizer(dropinRepositories, "|"); //$NON-NLS-1$
while (tokenizer.hasMoreTokens()) {
try {
result.add(new URI(tokenizer.nextToken()));
} catch (URISyntaxException e) {
//skip
}
}
}
}
}
} catch (IllegalStateException e) {
//unable to read profile, may be read only
result.add(areaFile.getParentFile().toURI());
}
//download cache
URI download = getDownloadCacheLocation(agent);
if (URIUtil.toFile(download).exists())
result.add(download);
}
}
return result;
}
private static String PROFILE_TIMESTAMP = "timestamp"; //$NON-NLS-1$
private static String PROFILE_ID = "profileId"; //$NON-NLS-1$
private static String PROFILE_DATA_AREA = "dataArea"; //$NON-NLS-1$
private static String PROFILE_REGISTRY = "registry"; //$NON-NLS-1$
private static Map<String, Object> extractProfileInformation(File target) {
if (target == null || !target.exists())
return null;
IPath path = new Path(target.getAbsolutePath());
if (!path.lastSegment().endsWith(PROFILE) && !path.lastSegment().endsWith(PROFILE_GZ))
return null;
//expect at least "p2/org.eclipse.equinox.p2.engine/profileRegistry/Profile.profile"
if (path.segmentCount() < 4)
return null;
Map<String, Object> results = new HashMap<>();
results.put(PROFILE_TIMESTAMP, Long.valueOf(-1));
String profileId = null;
if (target.isFile()) {
//p2/org.eclipse.equinox.p2.engine/profileRegistry/Profile.profile/123456.profile.gz
if (path.segmentCount() < 5)
return null;
String timestamp = path.lastSegment();
int idx = timestamp.indexOf('.');
if (idx > 0) {
timestamp = timestamp.substring(0, idx);
try {
results.put(PROFILE_TIMESTAMP, Long.valueOf(timestamp));
} catch (NumberFormatException e) {
//not a timestamp?
}
}
path = path.removeLastSegments(1);
profileId = path.removeFileExtension().lastSegment();
} else {
//target is the profile folder
profileId = path.removeFileExtension().lastSegment();
}
profileId = SimpleProfileRegistry.unescape(profileId);
results.put(PROFILE_ID, profileId);
//remove Profile.profile to get the registry folder
path = path.removeLastSegments(1);
results.put(PROFILE_REGISTRY, path.toFile());
//removing "org.eclipse.equinox.p2.engine/profileRegistry"
path = path.removeLastSegments(2);
results.put(PROFILE_DATA_AREA, path.toOSString());
return results;
}
public URI[] getContextMetadata() {
return contextMetadata;
}
public URI[] getContextArtifacts() {
return contextArtifacts;
}
public void setProductQualifier(String value) {
productQualifier = value;
}
/*
* If the user has specified a platform properties then load it.
*/
public void setPlatformProperties(String filename) {
if (filename == null || filename.trim().length() == 0)
return;
File file = new File(filename);
if (!file.exists())
return;
platformProperties = new Properties();
InputStream input = null;
try {
input = new BufferedInputStream(new FileInputStream(file));
platformProperties.load(input);
} catch (IOException e) {
platformProperties = null;
String message = NLS.bind(Messages.error_loading_platform_properties, filename);
IStatus status = new Status(IStatus.WARNING, IPDEBuildConstants.PI_PDEBUILD, message, e);
BundleHelper.getDefault().getLog().log(status);
} finally {
if (input != null)
try {
input.close();
} catch (IOException e) {
// ignore
}
}
}
protected void generateProductReplaceTask(ProductFile product, String productFilePath, AssemblyInformation assemblyInfo) {
if (product == null)
return;
BuildTimeSite site = null;
try {
site = getSite(false);
} catch (CoreException e1) {
return;
}
String version = product.getVersion();
if (version.endsWith(PROPERTY_QUALIFIER)) {
Version oldVersion = new Version(version);
version = oldVersion.getMajor() + "." + oldVersion.getMinor() + "." + oldVersion.getMicro() + "." + Utils.getPropertyFormat(PROPERTY_P2_PRODUCT_QUALIFIER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
List<FeatureEntry> productEntries = product.getProductEntries();
String mappings = Utils.getEntryVersionMappings(productEntries.toArray(new FeatureEntry[productEntries.size()]), site, assemblyInfo);
script.println("<eclipse.idReplacer productFilePath=\"" + AntScript.getEscaped(productFilePath) + "\""); //$NON-NLS-1$ //$NON-NLS-2$
script.println(" selfVersion=\"" + version + "\" "); //$NON-NLS-1$ //$NON-NLS-2$
if (product.useFeatures())
script.println(" featureIds=\"" + mappings + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$
else
script.println(" pluginIds=\"" + mappings + "\"/>"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
}