| /******************************************************************************* |
| * Copyright (c) 2000, 2013 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * 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 = new FilenameFilter() { |
| @Override |
| public boolean accept(File dir, String name) { |
| return 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 = new FilenameFilter() { |
| @Override |
| public boolean accept(File dir, String name) { |
| return 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 static boolean buildingOSGi = true; |
| 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<String>(); |
| protected List<String> pluginsForFilterRoots = new ArrayList<String>(); |
| protected boolean filterP2Base = false; |
| |
| protected boolean reportResolutionErrors; |
| |
| static { |
| // By default, a generic configuration is set |
| configInfos = new ArrayList<Config>(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 { |
| configInfos.clear(); |
| String[] configs = Utils.getArrayFromStringWithBlank(spec, "&"); //$NON-NLS-1$ |
| configInfos = new ArrayList<Config>(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())) |
| configInfos.add(Config.genericConfig()); |
| else |
| configInfos.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$ |
| } |
| |
| 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)); |
| try { |
| result.load(input); |
| } finally { |
| input.close(); |
| } |
| } 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 void setBuildingOSGi(boolean b) { |
| buildingOSGi = b; |
| } |
| |
| public static boolean isBuildingOSGi() { |
| return buildingOSGi; |
| } |
| |
| 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$ |
| } |
| |
| public static boolean getDefaultBuildingOSGi() { |
| return true; |
| } |
| |
| 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<URI>(); |
| 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<URI>(); |
| 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<URI>(); |
| 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<URI>(); |
| 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>(); |
| 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<String, Object>(); |
| results.put(PROFILE_TIMESTAMP, new Long(-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, new Long(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; |
| } |
| } |