Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/PreviousConfigurationFinder.java')
-rw-r--r--bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/PreviousConfigurationFinder.java306
1 files changed, 306 insertions, 0 deletions
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/PreviousConfigurationFinder.java b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/PreviousConfigurationFinder.java
new file mode 100644
index 000000000..9aa6f2303
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk.scheduler/src/org/eclipse/equinox/internal/p2/ui/sdk/scheduler/PreviousConfigurationFinder.java
@@ -0,0 +1,306 @@
+package org.eclipse.equinox.internal.p2.ui.sdk.scheduler;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.core.runtime.URIUtil;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
+import org.eclipse.equinox.p2.engine.IProfile;
+import org.eclipse.equinox.p2.engine.IProfileRegistry;
+
+public class PreviousConfigurationFinder {
+
+ private static final Pattern path = Pattern.compile("(.+)_(.*)_(\\d+)_.*"); //$NON-NLS-1$
+
+ static class Identifier {
+ private static final String DELIM = ". _-"; //$NON-NLS-1$
+ private int major, minor, service;
+
+ Identifier(int major, int minor, int service) {
+ super();
+ this.major = major;
+ this.minor = minor;
+ this.service = service;
+ }
+
+ /**
+ * @throws NumberFormatException if cannot parse the major and minor version components
+ */
+ Identifier(String versionString) {
+ super();
+ StringTokenizer tokenizer = new StringTokenizer(versionString, DELIM);
+
+ // major
+ if (tokenizer.hasMoreTokens())
+ major = Integer.parseInt(tokenizer.nextToken());
+
+ // minor
+ if (tokenizer.hasMoreTokens())
+ minor = Integer.parseInt(tokenizer.nextToken());
+
+ try {
+ // service
+ if (tokenizer.hasMoreTokens())
+ service = Integer.parseInt(tokenizer.nextToken());
+ } catch (NumberFormatException nfe) {
+ // ignore the service qualifier in that case and default to 0
+ // this will allow us to tolerate other non-conventional version numbers
+ }
+ }
+
+ /**
+ * Returns true if this id is considered to be greater than or equal to the given baseline.
+ * e.g.
+ * 1.2.9 >= 1.3.1 -> false
+ * 1.3.0 >= 1.3.1 -> false
+ * 1.3.1 >= 1.3.1 -> true
+ * 1.3.2 >= 1.3.1 -> true
+ * 2.0.0 >= 1.3.1 -> true
+ */
+ boolean isGreaterEqualTo(Identifier minimum) {
+ if (major < minimum.major)
+ return false;
+ if (major > minimum.major)
+ return true;
+ // major numbers are equivalent so check minor
+ if (minor < minimum.minor)
+ return false;
+ if (minor > minimum.minor)
+ return true;
+ // minor numbers are equivalent so check service
+ return service >= minimum.service;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof Identifier)
+ return false;
+ Identifier o = (Identifier) other;
+ if (major == o.major && minor == o.minor && service == o.service)
+ return true;
+ return false;
+ }
+ }
+
+ static class ConfigurationData {
+ String productId;
+ Identifier version;
+ String installPathHashcode;
+ File config;
+
+ public ConfigurationData(String productId, Identifier version, String installPathHashcode, File config) {
+ this.productId = productId;
+ this.version = version;
+ this.installPathHashcode = installPathHashcode;
+ this.config = config;
+ }
+
+ public String getProductId() {
+ return productId;
+ }
+
+ public Identifier getVersion() {
+ return version;
+ }
+
+ public String getInstallPathHashcode() {
+ return installPathHashcode;
+ }
+
+ public File getConfig() {
+ return config;
+ }
+ }
+
+ private File currentConfig;
+
+ public PreviousConfigurationFinder(File currentConfiguration) {
+ currentConfig = currentConfiguration;
+ }
+
+ private ConfigurationData extractConfigurationData(File candidate) {
+ Matcher m = path.matcher(candidate.getName());
+ if (!m.matches())
+ return null;
+ return new ConfigurationData(m.group(1), new Identifier(m.group(2)), m.group(3), candidate.getAbsoluteFile());
+ }
+
+ public IProfile findPreviousInstalls(File searchRoot, File installFolder) {
+ List<ConfigurationData> potentialConfigurations = readPreviousConfigurations(searchRoot);
+ Object[] productInfo = loadEclipseProductFile(installFolder);
+ ConfigurationData match = findMostRelevantConfiguration(potentialConfigurations, getInstallDirHash(installFolder), productInfo);
+ if (match == null)
+ match = findMostRelevantConfiguration(potentialConfigurations, productInfo);
+ if (match == null)
+ return null;
+ return fromConfigurationToProfile(match.getConfig());
+ }
+
+ private IProfile fromConfigurationToProfile(File configurationFolder) {
+ //TODO dispose the agent
+ String toBeImportedProfileId = null;
+ File config = new File(configurationFolder, "configuration/config.ini"); //$NON-NLS-1$
+ URI configArea = config.getParentFile().toURI();
+ InputStream is = null;
+ // default area
+ File p2DataArea = new File(configurationFolder, "p2"); //$NON-NLS-1$
+ try {
+ Properties props = new Properties();
+ is = new FileInputStream(config);
+ props.load(is);
+ toBeImportedProfileId = props.getProperty("eclipse.p2.profile"); //$NON-NLS-1$
+ String url = props.getProperty("eclipse.p2.data.area"); //$NON-NLS-1$
+ if (url != null) {
+ final String CONFIG_DIR = "@config.dir/"; //$NON-NLS-1$
+ final String FILE_PROTOCOL = "file:"; //$NON-NLS-1$
+ if (url.startsWith(CONFIG_DIR))
+ url = FILE_PROTOCOL + url.substring(CONFIG_DIR.length());
+ p2DataArea = new File(URIUtil.makeAbsolute(URIUtil.fromString(new File(url.substring(FILE_PROTOCOL.length())).isAbsolute() ? url : url.substring(FILE_PROTOCOL.length())), configArea));
+ }
+ } catch (IOException ioe) {
+ //ignore
+ } catch (URISyntaxException e) {
+ return null;
+ } finally {
+ try {
+ is.close();
+ } catch (IOException ioe) {
+ //ignore
+ }
+ is = null;
+ }
+ if (p2DataArea.exists()) {
+ IProvisioningAgent agent = null;
+ try {
+ agent = AutomaticUpdatePlugin.getDefault().getAgentProvider().createAgent(p2DataArea.toURI());
+ } catch (ProvisionException e) {
+ //Can't happen
+ }
+ IProfileRegistry registry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
+ if (toBeImportedProfileId != null)
+ return registry.getProfile(toBeImportedProfileId);
+
+ //TODO we may need to set the SELF profile on the registry to load the repos
+ IProfile[] allProfiles = registry.getProfiles();
+ if (allProfiles.length == 1)
+ return allProfiles[0];
+
+ // IMetadataRepositoryManager metadataRepoMgr = (IMetadataRepositoryManager) agent.getService(IMetadataRepositoryManager.SERVICE_NAME);
+ // URI[] metadataRepos = metadataRepoMgr.getKnownRepositories(IRepositoryManager.REPOSITORIES_NON_SYSTEM);
+ //TODO deal with the repos
+ }
+ return null;
+ }
+
+ private ConfigurationData findMostRelevantConfiguration(List<ConfigurationData> configurations, String installDirHash, Object[] productInfo) {
+ ConfigurationData bestMatch = null;
+ int numberOfcriteriaMet = 0;
+ for (ConfigurationData candidate : configurations) {
+ int criteriaMet = 0;
+ if (!candidate.getInstallPathHashcode().equals(installDirHash))
+ continue;
+ criteriaMet++;
+ if (!candidate.getProductId().equals(productInfo[0]))
+ continue;
+ criteriaMet++;
+ if (!candidate.getVersion().equals(productInfo[1]))
+ continue; //This is most likely ourselves
+ criteriaMet++;
+ if (criteriaMet > numberOfcriteriaMet) {
+ bestMatch = candidate;
+ numberOfcriteriaMet = criteriaMet;
+ } else if (criteriaMet == numberOfcriteriaMet) {
+ if (bestMatch.getConfig().lastModified() < candidate.getConfig().lastModified())
+ bestMatch = candidate;
+ }
+ }
+ return bestMatch;
+ }
+
+ //Out of a set of configuration, find the one with the most similar product info.
+ //TODO do we look for the higer or lower versions?
+ private ConfigurationData findMostRelevantConfiguration(List<ConfigurationData> configurations, Object[] productInfo) {
+ ConfigurationData bestMatch = null;
+ int numberOfcriteriaMet = 0;
+ for (ConfigurationData candidate : configurations) {
+ int criteriaMet = 0;
+ criteriaMet++;
+ if (!candidate.getProductId().equals(productInfo[0]))
+ continue;
+ criteriaMet++;
+ if (candidate.getVersion().equals(productInfo[1]))
+ continue; //This is most likely ourselves
+ else if (bestMatch != null && (candidate.getVersion().equals(bestMatch.getVersion())))
+ criteriaMet++;
+ if (criteriaMet > numberOfcriteriaMet) {
+ bestMatch = candidate;
+ numberOfcriteriaMet = criteriaMet;
+ } else if (criteriaMet == numberOfcriteriaMet) {
+ if (bestMatch.getConfig().lastModified() < candidate.getConfig().lastModified())
+ bestMatch = candidate;
+ }
+ }
+ return bestMatch;
+ }
+
+ //Load the .eclipseproduct file in the base of the installation. This logic is very similar to the one found in the launcher
+ private Object[] loadEclipseProductFile(File installDir) {
+ final String ECLIPSE = "eclipse"; //$NON-NLS-1$
+ final String PRODUCT_SITE_MARKER = ".eclipseproduct"; //$NON-NLS-1$
+ final String PRODUCT_SITE_ID = "id"; //$NON-NLS-1$
+ final String PRODUCT_SITE_VERSION = "version"; //$NON-NLS-1$
+
+ File eclipseProduct = new File(installDir, PRODUCT_SITE_MARKER);
+ String appId = null;
+ Identifier appVersion = null;
+ if (eclipseProduct.exists()) {
+ Properties props = new Properties();
+ try {
+ props.load(new FileInputStream(eclipseProduct));
+ appId = props.getProperty(PRODUCT_SITE_ID);
+ if (appId == null || appId.trim().length() == 0)
+ appId = ECLIPSE;
+ String version = props.getProperty(PRODUCT_SITE_VERSION);
+ if (version == null || version.trim().length() == 0)
+ appVersion = new Identifier(0, 0, 0);
+ else
+ appVersion = new Identifier(version);
+
+ } catch (IOException e) {
+ return new String[0];
+ }
+ } else {
+ return new String[0];
+ }
+ return new Object[] {appId, appVersion};
+ }
+
+ //Iterate through a folder to look for potential configuration folders and reify them.
+ private List<ConfigurationData> readPreviousConfigurations(File configurationFolder) {
+ File[] candidates = configurationFolder.listFiles();
+ List<ConfigurationData> configurations = new ArrayList<ConfigurationData>(candidates.length);
+ for (File candidate : candidates) {
+ if (!candidate.isDirectory())
+ continue;
+ if (candidate.equals(currentConfig))
+ continue;
+ ConfigurationData tmp = extractConfigurationData(candidate);
+ if (tmp != null)
+ configurations.add(tmp);
+ }
+ return configurations;
+ }
+
+ //Simplified code computing the hashCode of the install location. The real runtime code is in the launcher
+ private String getInstallDirHash(File installFolder) {
+ try {
+ return Integer.toString(installFolder.getCanonicalPath().hashCode());
+ } catch (IOException e) {
+ return ""; //$NON-NLS-1$
+ }
+ }
+}

Back to the top