| /******************************************************************************* |
| * Copyright (c) 2000, 2008 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 Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.update.internal.core; |
| |
| import org.eclipse.update.internal.model.SiteLocalModel; |
| |
| import org.eclipse.core.runtime.ListenerList; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.FileLocator; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.update.configuration.IActivity; |
| import org.eclipse.update.configuration.IConfiguredSite; |
| import org.eclipse.update.configuration.IInstallConfiguration; |
| import org.eclipse.update.configuration.IInstallConfigurationChangedListener; |
| import org.eclipse.update.configuration.IProblemHandler; |
| import org.eclipse.update.configurator.ConfiguratorUtils; |
| import org.eclipse.update.configurator.IPlatformConfiguration; |
| import org.eclipse.update.core.FeatureContentProvider; |
| import org.eclipse.update.core.IFeature; |
| import org.eclipse.update.core.IFeatureReference; |
| import org.eclipse.update.core.IPluginEntry; |
| import org.eclipse.update.core.ISite; |
| import org.eclipse.update.core.ISiteContentProvider; |
| import org.eclipse.update.core.ISiteFeatureReference; |
| import org.eclipse.update.core.Site; |
| import org.eclipse.update.core.SiteManager; |
| import org.eclipse.update.core.Utilities; |
| import org.eclipse.update.core.VersionedIdentifier; |
| import org.eclipse.update.core.model.SiteModel; |
| import org.eclipse.update.internal.configurator.ConfigurationActivator; |
| import org.eclipse.update.internal.configurator.FeatureEntry; |
| import org.eclipse.update.internal.configurator.PlatformConfiguration; |
| import org.eclipse.update.internal.configurator.PluginEntry; |
| import org.eclipse.update.internal.configurator.SiteEntry; |
| import org.eclipse.update.internal.model.ConfigurationActivityModel; |
| import org.eclipse.update.internal.model.ConfiguredSiteModel; |
| import org.eclipse.update.internal.model.InstallConfigurationModel; |
| import org.osgi.framework.Bundle; |
| |
| /** |
| * Manages ConfiguredSites |
| * |
| */ |
| |
| public class InstallConfiguration extends InstallConfigurationModel implements IInstallConfiguration { |
| private static boolean isWindows = System.getProperty("os.name").startsWith("Win"); //$NON-NLS-1$ //$NON-NLS-2$ |
| private ListenerList listeners = new ListenerList(ListenerList.IDENTITY); |
| |
| /* |
| * default constructor. |
| */ |
| public InstallConfiguration() { |
| } |
| |
| /* |
| * Copy constructor |
| * @since 3.0 |
| */ |
| public InstallConfiguration(IInstallConfiguration config) throws MalformedURLException, CoreException { |
| this(config, null, null); |
| } |
| |
| /* |
| * copy constructor |
| */ |
| public InstallConfiguration(IInstallConfiguration config, URL newLocation, String label) throws CoreException, MalformedURLException { |
| // set current date and timeline as caller can call setDate if the |
| // date on the URL string has to be the same |
| Date now = new Date(); |
| setCreationDate(now); |
| setCurrent(false); |
| |
| if (newLocation == null) { |
| String newFileName = UpdateManagerUtils.getLocalRandomIdentifier(SiteLocalModel.CONFIG_FILE, now); |
| newLocation = UpdateManagerUtils.getURL(((LocalSite)SiteManager.getLocalSite()).getLocationURL(), newFileName, null); |
| } |
| setLocationURLString(newLocation.toExternalForm()); |
| |
| if (label == null) |
| label = Utilities.format(now); |
| setLabel(label); |
| |
| // do not copy list of listeners nor activities |
| // make a copy of the siteConfiguration object |
| if (config != null) { |
| IConfiguredSite[] csites = config.getConfiguredSites(); |
| if (csites != null) { |
| for (int i = 0; i < csites.length; i++) { |
| ConfiguredSite configSite = new ConfiguredSite(csites[i]); |
| addConfigurationSiteModel(configSite); |
| } |
| } |
| } |
| |
| resolve(newLocation, null); |
| // no need to parse file, all data are initialized |
| initialized = true; |
| } |
| |
| |
| /* |
| * Returns the list of configured sites or an empty array |
| */ |
| public IConfiguredSite[] getConfiguredSites() { |
| ConfiguredSiteModel[] result = getConfigurationSitesModel(); |
| if (result.length == 0) |
| return new IConfiguredSite[0]; |
| else |
| return (IConfiguredSite[]) result; |
| } |
| |
| /* |
| * Returns the default site policy |
| */ |
| private int getDefaultPolicy() { |
| return PlatformConfiguration.getDefaultPolicy(); |
| } |
| |
| /** |
| * Creates a Configuration Site and a new Site |
| * The policy is from <code> org.eclipse.core.boot.IPlatformConfiguration</code> |
| */ |
| public IConfiguredSite createConfiguredSite(File file) throws CoreException { |
| |
| if (!file.getName().equals("eclipse")) { //$NON-NLS-1$ |
| file = new File(file, "eclipse"); //$NON-NLS-1$ |
| file.mkdirs(); |
| } |
| |
| if (isDuplicateSite(file)) |
| throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_location_exists, (new String[] { file.getPath() })),null); |
| ISite site = InternalSiteManager.createSite(file); |
| |
| //create a config site around the site |
| // even if the site == null |
| BaseSiteLocalFactory factory = new BaseSiteLocalFactory(); |
| ConfiguredSite configSite = (ConfiguredSite) factory.createConfigurationSiteModel((SiteModel) site, getDefaultPolicy()); |
| |
| if (configSite.isNativelyLinked()) { |
| throw Utilities.newCoreException(Messages.InstallConfiguration_AlreadyNativelyLinked, null); |
| } |
| |
| if (configSite.isProductSite()) { |
| throw Utilities.newCoreException(Messages.InstallConfiguration_AlreadyProductSite, null); |
| } |
| |
| if (site != null) { |
| configSite.setPlatformURLString(site.getURL().toExternalForm()); |
| |
| // obtain the list of plugins |
| IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration(); |
| ConfigurationPolicy configurationPolicy = configSite.getConfigurationPolicy(); |
| String[] pluginPath = new String[0]; |
| if (configurationPolicy.getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) |
| pluginPath = configurationPolicy.getPluginPath(site); |
| |
| // create new Site in configuration |
| IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath); |
| |
| // change runtime |
| IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.createSiteEntry(site.getURL(), sitePolicy); |
| runtimeConfiguration.configureSite(siteEntry); |
| |
| // if the privatre marker doesn't already exist create it |
| configSite.createPrivateSiteMarker(); |
| ((SiteModel)site).setConfiguredSiteModel(configSite); |
| } |
| // configure all features as enable |
| configure(configSite); |
| |
| return configSite; |
| } |
| |
| /** |
| * Creates a Configuration Site and a new Site as a private link site |
| * The policy is from <code> org.eclipse.core.boot.IPlatformConfiguration</code> |
| */ |
| public IConfiguredSite createLinkedConfiguredSite(File file) throws CoreException { |
| return createConfiguredSite(file); |
| // if (isDuplicateSite(file)) |
| // throw Utilities.newCoreException(UpdateUtils.getFormattedMessage("InstallConfiguration.location.exists", file.getPath()),null); |
| // |
| // ISite site = InternalSiteManager.createSite(file); |
| // |
| // //create a config site around the site |
| // // even if the site == null |
| // BaseSiteLocalFactory factory = new BaseSiteLocalFactory(); |
| // ConfiguredSite configSite = (ConfiguredSite) factory.createConfigurationSiteModel((SiteModel) site, getDefaultPolicy()); |
| // |
| // if (!configSite.isExtensionSite()) { |
| // String msg = Policy.bind("InstallConfiguration.NotAnExtensionSite"); |
| // throw Utilities.newCoreException(msg, null); |
| // } |
| // |
| // if (configSite.isNativelyLinked()) { |
| // throw Utilities.newCoreException("InstallConfiguration.AlreadyNativelyLinked", null); |
| // } |
| // |
| // if (site != null) { |
| // configSite.setPlatformURLString(site.getURL().toExternalForm()); |
| // |
| // // obtain the list of plugins |
| // IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration(); |
| // ConfigurationPolicy configurationPolicy = configSite.getConfigurationPolicy(); |
| // String[] pluginPath = new String[0]; |
| // if (configurationPolicy.getPolicy() == IPlatformConfiguration.ISitePolicy.USER_INCLUDE) |
| // pluginPath = configurationPolicy.getPluginPath(site); |
| // |
| // // create new Site in configuration |
| // IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath); |
| // |
| // // change runtime |
| // IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.createSiteEntry(site.getURL(), sitePolicy); |
| // runtimeConfiguration.configureSite(siteEntry); |
| // |
| // } |
| // |
| // // configure all features as enable |
| // configure(configSite); |
| // |
| // return configSite; |
| } |
| |
| /* |
| *Configure all features as Enable Check we only enable highest version |
| */ |
| private void configure(ConfiguredSite linkedSite) throws CoreException { |
| ISite site = linkedSite.getSite(); |
| ISiteFeatureReference[] newFeaturesRef = site.getFeatureReferences(); |
| |
| for (int i = 0; i < newFeaturesRef.length; i++) { |
| // TRACE |
| if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_RECONCILER) { |
| String reconciliationType = "enable (optimistic)"; //$NON-NLS-1$ |
| UpdateCore.debug("New Linked Site:New Feature: " + newFeaturesRef[i].getURL() + " as " + reconciliationType); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| ConfigurationPolicy policy = linkedSite.getConfigurationPolicy(); |
| policy.configure(newFeaturesRef[i], true, false); |
| } |
| SiteReconciler.checkConfiguredFeatures(linkedSite); |
| } |
| |
| /* |
| * |
| */ |
| public void addConfiguredSite(IConfiguredSite site) { |
| if (!isCurrent() && isReadOnly()) |
| return; |
| |
| ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_SITE_INSTALL); |
| activity.setLabel(site.getSite().getURL().toExternalForm()); |
| activity.setDate(new Date()); |
| ConfiguredSiteModel configSiteModel = (ConfiguredSiteModel) site; |
| addConfigurationSiteModel(configSiteModel); |
| configSiteModel.setInstallConfigurationModel(this); |
| |
| // notify listeners |
| Object[] configurationListeners = listeners.getListeners(); |
| for (int i = 0; i < configurationListeners.length; i++) { |
| IInstallConfigurationChangedListener listener = ((IInstallConfigurationChangedListener) configurationListeners[i]); |
| listener.installSiteAdded(site); |
| } |
| |
| // everything done ok |
| activity.setStatus(IActivity.STATUS_OK); |
| this.addActivity(activity); |
| } |
| |
| /** |
| * Method addActivity. |
| * @param activity |
| */ |
| public void addActivity(IActivity activity) { |
| addActivityModel((ConfigurationActivityModel)activity); |
| } |
| |
| /* |
| * |
| */ |
| public void removeConfiguredSite(IConfiguredSite site) { |
| if (!isCurrent() && isReadOnly()) |
| return; |
| |
| if (removeConfigurationSiteModel((ConfiguredSiteModel) site)) { |
| // notify listeners |
| Object[] configurationListeners = listeners.getListeners(); |
| for (int i = 0; i < configurationListeners.length; i++) { |
| IInstallConfigurationChangedListener listener = ((IInstallConfigurationChangedListener) configurationListeners[i]); |
| listener.installSiteRemoved(site); |
| } |
| |
| //activity |
| ConfigurationActivity activity = new ConfigurationActivity(IActivity.ACTION_SITE_REMOVE); |
| activity.setLabel(site.getSite().getURL().toExternalForm()); |
| activity.setDate(new Date()); |
| activity.setStatus(IActivity.STATUS_OK); |
| this.addActivity(activity); |
| } |
| } |
| |
| /* |
| * @see IInstallConfiguration#addInstallConfigurationChangedListener(IInstallConfigurationChangedListener) |
| */ |
| public void addInstallConfigurationChangedListener(IInstallConfigurationChangedListener listener) { |
| listeners.add(listener); |
| } |
| |
| /* |
| * @see IInstallConfiguration#removeInstallConfigurationChangedListener(IInstallConfigurationChangedListener) |
| */ |
| public void removeInstallConfigurationChangedListener(IInstallConfigurationChangedListener listener) { |
| listeners.remove(listener); |
| } |
| |
| |
| /* |
| * Deletes the configuration from its URL/location |
| */ |
| public void remove() { |
| // save the configuration |
| if ("file".equalsIgnoreCase(getURL().getProtocol())) { //$NON-NLS-1$ |
| // the location points to a file |
| File file = new File(getURL().getFile()); |
| UpdateManagerUtils.removeFromFileSystem(file); |
| } |
| } |
| |
| /** |
| * Saves the configuration into its URL/location |
| * and changes the platform configuration. |
| * The runtime site entries from platform.xml are updated as required |
| * (cannot recreate these because must preserve other runtime state) [18520] |
| * @return true if restart is needed |
| */ |
| public boolean save() throws CoreException { |
| |
| // Write info into platform for the next runtime |
| IPlatformConfiguration runtimeConfiguration = ConfiguratorUtils.getCurrentPlatformConfiguration(); |
| ConfiguredSiteModel[] configurationSites = getConfigurationSitesModel(); |
| |
| // clean configured Entries from platform runtime |
| IPlatformConfiguration.IFeatureEntry[] configuredFeatureEntries = runtimeConfiguration.getConfiguredFeatureEntries(); |
| for (int i = 0; i < configuredFeatureEntries.length; i++) { |
| runtimeConfiguration.unconfigureFeatureEntry(configuredFeatureEntries[i]); |
| } |
| |
| // [19958] remember sites currently configured by runtime (use |
| // temp configuration object rather than a straight list to ensure |
| // correct lookup) |
| IPlatformConfiguration tempConfig = null; |
| try { |
| tempConfig = ConfiguratorUtils.getPlatformConfiguration(null); |
| IPlatformConfiguration.ISiteEntry[] tmpSites = runtimeConfiguration.getConfiguredSites(); |
| for (int i = 0; i < tmpSites.length; i++) { |
| tempConfig.configureSite(tmpSites[i]); |
| } |
| } catch (IOException e) { |
| // assume no currently configured sites |
| } |
| |
| //check sites |
| checkSites(configurationSites, runtimeConfiguration); |
| |
| // Save the plugin path, primary feature and platform |
| for (int i = 0; i < configurationSites.length; i++) { |
| ConfiguredSite cSite = ((ConfiguredSite) configurationSites[i]); |
| ConfigurationPolicy configurationPolicy = cSite.getConfigurationPolicy(); |
| |
| savePluginPath(cSite, runtimeConfiguration, tempConfig); |
| |
| // IF primary feature URL or platform feature URL that we need to pass to runtime config |
| // is part of platform:base:, write it as platform:base: URL |
| IFeatureReference[] configuredFeaturesRef = configurationPolicy.getConfiguredFeatures(); |
| for (int j = 0; j < configuredFeaturesRef.length; j++) { |
| IFeature feature = null; |
| try { |
| feature = configuredFeaturesRef[j].getFeature(null); |
| } catch (CoreException e) { |
| UpdateCore.warn(null, e); |
| } |
| saveFeatureEntry(cSite, feature, runtimeConfiguration); |
| } |
| } |
| |
| // [19958] remove any extra site entries from runtime configuration |
| // (site entries that no longer exist in this configuration) |
| if (tempConfig != null) { |
| IPlatformConfiguration.ISiteEntry[] tmpSites = tempConfig.getConfiguredSites(); |
| for (int i = 0; i < tmpSites.length; i++) { |
| runtimeConfiguration.unconfigureSite(tmpSites[i]); |
| } |
| } |
| |
| try { |
| runtimeConfiguration.save(); |
| // log configuration and activities |
| this.date = new Date(runtimeConfiguration.getChangeStamp()); |
| if ("file".equalsIgnoreCase(getURL().getProtocol())) //$NON-NLS-1$ |
| UpdateCore.log(this); |
| resetActivities(); |
| return isRestartNeeded(runtimeConfiguration); |
| } catch (IOException e) { |
| CoreException exc = Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToSavePlatformConfiguration, (new String[] { runtimeConfiguration.getConfigurationLocation().toExternalForm() })), e); |
| UpdateCore.warn("",exc); //$NON-NLS-1$ |
| } |
| return true; |
| } |
| |
| /* |
| * Write the plugin path for each site |
| * Do not check if the site already existed before [16696]. |
| * Reuse any runtime site objects in platform.cfg (to preserve state) [18520]. |
| */ |
| private void savePluginPath(ConfiguredSite cSite, IPlatformConfiguration runtimeConfiguration, IPlatformConfiguration tempConfig) // [19958] |
| throws CoreException { |
| |
| ConfigurationPolicy configurationPolicy = cSite.getConfigurationPolicy(); |
| |
| // create a ISitePolicy (policy, pluginPath) |
| // for the site |
| String[] pluginPath = configurationPolicy.getPluginPath(cSite.getSite()); |
| IPlatformConfiguration.ISitePolicy sitePolicy = runtimeConfiguration.createSitePolicy(configurationPolicy.getPolicy(), pluginPath); |
| |
| // get the URL of the site that matches the one platform.cfg gave us |
| URL urlToCheck = null; |
| try { |
| urlToCheck = new URL(cSite.getPlatformURLString()); |
| } catch (MalformedURLException e) { |
| throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { cSite.getPlatformURLString() })), e); |
| } catch (ClassCastException e) { |
| throw Utilities.newCoreException(Messages.InstallConfiguration_UnableToCast, e); |
| } |
| |
| // update runtime configuration [18520] |
| // Note: we must not blindly replace the site entries because they |
| // contain additional runtime state that needs to be preserved. |
| IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.findConfiguredSite(urlToCheck); |
| if (siteEntry == null) |
| siteEntry = runtimeConfiguration.createSiteEntry(urlToCheck, sitePolicy); |
| else { |
| siteEntry.setSitePolicy(sitePolicy); |
| ((SiteEntry)siteEntry).refreshPlugins(); |
| if (tempConfig != null) // [19958] remove reused entries from list |
| tempConfig.unconfigureSite(siteEntry); |
| } |
| ((SiteEntry)siteEntry).setEnabled(cSite.isEnabled()); |
| runtimeConfiguration.configureSite(siteEntry, true /*replace if exists*/); |
| } |
| |
| /* |
| * Save the Feature entry |
| * The feature can be a primary feature and/or a platform feature |
| */ |
| private void saveFeatureEntry(ConfiguredSite cSite, IFeature feature, IPlatformConfiguration runtimeConfiguration) throws CoreException { |
| if (feature == null) |
| return; |
| |
| // get the URL of the plugin that corresponds to the feature (pluginid = featureid) |
| String id = feature.getVersionedIdentifier().getIdentifier(); |
| IPluginEntry[] entries = feature.getPluginEntries(); |
| URL url = null; |
| IPluginEntry featurePlugin = null; |
| for (int k = 0; k < entries.length; k++) { |
| if (id.equalsIgnoreCase(entries[k].getVersionedIdentifier().getIdentifier())) { |
| url = getRuntimeConfigurationURL(entries[k], cSite); |
| featurePlugin = entries[k]; |
| break; |
| } |
| } |
| String pluginVersion = null; |
| if (featurePlugin != null) |
| pluginVersion = featurePlugin.getVersionedIdentifier().getVersion().toString(); |
| |
| // Find the site |
| SiteEntry siteEntry = null; |
| try { |
| URL featureUrl = new URL(cSite.getPlatformURLString()); |
| siteEntry = (SiteEntry)runtimeConfiguration.findConfiguredSite(featureUrl); |
| } catch (MalformedURLException e) { |
| throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { cSite.getPlatformURLString() })), e); |
| } catch (ClassCastException e) { |
| throw Utilities.newCoreException(Messages.InstallConfiguration_UnableToCast, e); |
| } |
| |
| // if the URL doesn't exist throw a CoreException |
| if (siteEntry == null) { |
| throw new CoreException( |
| new Status(IStatus.ERROR, UpdateCore.getPlugin().getBundle().getSymbolicName(), |
| NLS.bind(Messages.InstallConfiguration_unableToFindSite, (new String[] { cSite.getSite().getURL().toExternalForm(), runtimeConfiguration.getConfigurationLocation().toExternalForm() })))); |
| } |
| |
| // write the primary features |
| if (feature.isPrimary()) { |
| // get any fragments for the feature plugin |
| ArrayList list = new ArrayList(); |
| if (url != null) |
| list.add(url); |
| if (featurePlugin != null) { |
| URL[] fragments = getRuntimeFragmentURLs(featurePlugin); |
| list.addAll(Arrays.asList(fragments)); |
| } |
| URL[] roots = (URL[]) list.toArray(new URL[0]); |
| String pluginIdentifier = feature.getPrimaryPluginID(); |
| |
| // save information in runtime platform state |
| String version = feature.getVersionedIdentifier().getVersion().toString(); |
| String application = feature.getApplication(); |
| FeatureEntry featureEntry = (FeatureEntry)runtimeConfiguration.createFeatureEntry(id, version, pluginIdentifier, pluginVersion, true, application, roots); |
| featureEntry.setURL(getFeatureRelativeURL(feature)); |
| siteEntry.addFeatureEntry(featureEntry); |
| } else { |
| // write non-primary feature entries |
| String version = feature.getVersionedIdentifier().getVersion().toString(); |
| String pluginIdentifier = feature.getPrimaryPluginID(); |
| FeatureEntry featureEntry = (FeatureEntry)runtimeConfiguration.createFeatureEntry(id, version, pluginIdentifier, pluginVersion, false, null, null); |
| featureEntry.setURL(getFeatureRelativeURL(feature)); |
| siteEntry.addFeatureEntry(featureEntry); |
| } |
| |
| // write the platform features (features that contain special platform plugins) |
| IPluginEntry[] platformPlugins = getPlatformPlugins(feature, runtimeConfiguration); |
| for (int k = 0; k < platformPlugins.length; k++) { |
| id = platformPlugins[k].getVersionedIdentifier().getIdentifier(); |
| url = getRuntimeConfigurationURL(platformPlugins[k], cSite); |
| if (url != null) { |
| runtimeConfiguration.setBootstrapPluginLocation(id, url); |
| } |
| } |
| } |
| |
| /* |
| * Log if we are about to create a site that didn't exist before |
| * in platform.cfg [16696]. |
| */ |
| private void checkSites(ConfiguredSiteModel[] configurationSites, IPlatformConfiguration runtimeConfiguration) throws CoreException { |
| |
| // check all the sites we are about to write already existed |
| // they should have existed either because they were created by |
| // updateManager or because we read them from platform.cfg |
| for (int i = 0; i < configurationSites.length; i++) { |
| // get the URL of the site that matches the one platform.cfg gave us |
| URL urlToCheck = null; |
| try { |
| urlToCheck = new URL(configurationSites[i].getPlatformURLString()); |
| } catch (MalformedURLException e) { |
| UpdateCore.warn(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { configurationSites[i].getPlatformURLString() })), e); |
| } catch (ClassCastException e) { |
| UpdateCore.warn(Messages.InstallConfiguration_UnableToCast, e); |
| } |
| |
| // if the URL doesn't exits log it |
| IPlatformConfiguration.ISiteEntry siteEntry = runtimeConfiguration.findConfiguredSite(urlToCheck); |
| if (siteEntry == null) { |
| UpdateCore.warn(NLS.bind(Messages.InstallConfiguration_unableToFindSite, (new String[] { urlToCheck.toExternalForm(), runtimeConfiguration.getConfigurationLocation().toExternalForm() }))); |
| } |
| } |
| } |
| |
| |
| /* |
| * reverts this configuration to the match the new one |
| * |
| * Compare the oldSites with the currentOne. the old state is the state we want to revert to. |
| * |
| * If a site was in old state, but not in the currentOne, keep it in the hash. |
| * If a site is in the currentOne but was not in the old state, unconfigure all features and add it in the hash |
| * If a site was in baoth state, calculate the 'delta' and re-set it in the hash map |
| * |
| * At the end, set the configured site from the new sites hash map |
| * |
| */ |
| public void revertTo(IInstallConfiguration configuration, IProgressMonitor monitor, IProblemHandler handler) throws CoreException, InterruptedException { |
| |
| IConfiguredSite[] oldConfigSites = configuration.getConfiguredSites(); |
| IConfiguredSite[] nowConfigSites = this.getConfiguredSites(); |
| |
| // create a hashtable of the *old* and *new* sites |
| Map oldSitesMap = new Hashtable(0); |
| Map newSitesMap = new Hashtable(0); |
| for (int i = 0; i < oldConfigSites.length; i++) { |
| IConfiguredSite element = oldConfigSites[i]; |
| oldSitesMap.put(element.getSite().getURL().toExternalForm(), element); |
| newSitesMap.put(element.getSite().getURL().toExternalForm(), element); |
| } |
| // create list of all the sites that map the *old* sites |
| // we want the intersection between the old sites and the current sites |
| if (nowConfigSites != null) { |
| String key = null; |
| |
| for (int i = 0; i < nowConfigSites.length; i++) { |
| key = nowConfigSites[i].getSite().getURL().toExternalForm(); |
| IConfiguredSite oldSite = (IConfiguredSite) oldSitesMap.get(key); |
| if (oldSite != null) { |
| // the Site existed before, calculate the delta between its current state and the |
| // state we are reverting to and put it back into the map |
| ((ConfiguredSite) nowConfigSites[i]).revertTo(oldSite, monitor, handler); |
| } else { |
| // the site didn't exist in the InstallConfiguration we are reverting to |
| // unconfigure everything from this site so it is still present |
| ISiteFeatureReference[] featuresToUnconfigure = nowConfigSites[i].getSite().getFeatureReferences(); |
| for (int j = 0; j < featuresToUnconfigure.length; j++) { |
| IFeature featureToUnconfigure = null; |
| try { |
| featureToUnconfigure = featuresToUnconfigure[j].getFeature(null); |
| } catch (CoreException e) { |
| UpdateCore.warn(null, e); |
| } |
| if (featureToUnconfigure != null) |
| nowConfigSites[i].unconfigure(featureToUnconfigure); |
| } |
| } |
| newSitesMap.put(key,nowConfigSites[i]); |
| } |
| |
| // the new configuration has the exact same sites as the old configuration |
| // the old configuration in the Map are either as-is because they don't exist |
| // in the current one, or they are the delta from the current one to the old one |
| Collection sites = newSitesMap.values(); |
| if (sites != null && !sites.isEmpty()) { |
| ConfiguredSiteModel[] sitesModel = new ConfiguredSiteModel[sites.size()]; |
| sites.toArray(sitesModel); |
| setConfigurationSiteModel(sitesModel); |
| } |
| } |
| } |
| |
| /* |
| * @see IInstallConfiguration#getActivities() |
| */ |
| public IActivity[] getActivities() { |
| if (getActivityModel().length == 0) |
| return new IActivity[0]; |
| return (IActivity[]) getActivityModel(); |
| } |
| |
| /* |
| * returns the list of platform plugins of the feature or an empty list |
| * if the feature doesn't contain any platform plugins |
| */ |
| private IPluginEntry[] getPlatformPlugins(IFeature feature, IPlatformConfiguration runtimeConfiguration) { |
| Map featurePlatformPlugins = new HashMap(); |
| String[] platformPluginID = runtimeConfiguration.getBootstrapPluginIdentifiers(); |
| IPluginEntry[] featurePlugins = feature.getPluginEntries(); |
| |
| for (int i = 0; i < platformPluginID.length; i++) { |
| String featurePluginId = null; |
| for (int j = 0; j < featurePlugins.length; j++) { |
| featurePluginId = featurePlugins[j].getVersionedIdentifier().getIdentifier(); |
| if (platformPluginID[i].equals(featurePluginId)) { |
| featurePlatformPlugins.put(platformPluginID[i], featurePlugins[j]); |
| } |
| } |
| } |
| |
| Collection values = featurePlatformPlugins.values(); |
| if (values == null || values.size() == 0) |
| return new IPluginEntry[0]; |
| |
| IPluginEntry[] result = new IPluginEntry[values.size()]; |
| Iterator iter = values.iterator(); |
| int index = 0; |
| while (iter.hasNext()) { |
| result[index] = ((IPluginEntry) iter.next()); |
| index++; |
| } |
| return result; |
| } |
| |
| /* |
| * returns the URL of the pluginEntry on the site |
| * Transform the URL to use platform: protocol if needed |
| * return null if the URL to write is not valid |
| */ |
| private URL getRuntimeConfigurationURL(IPluginEntry entry, ConfiguredSite cSite) throws CoreException { |
| |
| String rootString = cSite.getPlatformURLString(); |
| String pluginPathID = getPathID(entry); |
| try { |
| ISiteContentProvider siteContentProvider = cSite.getSite().getSiteContentProvider(); |
| URL pluginEntryfullURL = siteContentProvider.getArchiveReference(pluginPathID); |
| |
| // |
| if (!rootString.startsWith("platform")) { //$NON-NLS-1$ |
| // DEBUG: |
| if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION) |
| UpdateCore.debug("getRuntimeConfiguration Plugin Entry Full URL:" + pluginEntryfullURL + " Platform String:" + rootString + " [NON PLATFORM URL]."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ |
| return pluginEntryfullURL; |
| } |
| |
| //URL pluginEntryRootURL = Platform.resolve(new URL(rootString)); |
| // Do not resolve [16507], just use platform:base/ as a root |
| // rootString = platform:base |
| // pluginRoot = /home/a |
| // pluginFull = /home/a/c/boot.jar |
| // relative = platform:/base/c/boot.jar |
| URL pluginEntryRootURL = cSite.getSite().getURL(); |
| String relativeString = UpdateManagerUtils.getURLAsString(pluginEntryRootURL, pluginEntryfullURL); |
| URL result = new URL(new URL(rootString), relativeString); |
| |
| // DEBUG: |
| if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION) |
| UpdateCore.debug("getRuntimeConfiguration plugin Entry Full URL:" + pluginEntryfullURL + " Platform String:" + rootString + " Site URL:" + pluginEntryRootURL + " Relative:" + relativeString); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ |
| |
| // verify we are about to write a valid file URL |
| // check with fullURL as it is not resolved to platform:base/ |
| if (pluginEntryfullURL != null) { |
| if ("file".equals(pluginEntryfullURL.getProtocol())) { //$NON-NLS-1$ |
| String fileString = pluginEntryfullURL.getFile(); |
| if (!new File(fileString).exists()) { |
| UpdateCore.warn("The URL:" + result + " doesn't point to a valid platform plugin.The URL will not be written in the platform configuration", new Exception()); //$NON-NLS-1$ //$NON-NLS-2$ |
| return null; |
| } |
| } |
| } |
| |
| return result; |
| } catch (IOException e) { |
| throw Utilities.newCoreException(NLS.bind(Messages.InstallConfiguration_UnableToCreateURL, (new String[] { rootString })), e); |
| } |
| } |
| |
| /* |
| * Return URLs for any fragments that are associated with the specified plugin entry |
| */ |
| private URL[] getRuntimeFragmentURLs(IPluginEntry entry) throws CoreException { |
| |
| // get the identifier associated with the entry |
| VersionedIdentifier vid = entry.getVersionedIdentifier(); |
| |
| // get the plugin descriptor from the registry |
| Bundle bundle = Platform.getBundle(vid.getIdentifier()); |
| ArrayList list = new ArrayList(); |
| if (bundle != null && bundle.getState() != Bundle.UNINSTALLED && bundle.getState() != Bundle.INSTALLED) { |
| FragmentEntry[] fragments = UpdateManagerUtils.getFragments(bundle); |
| for (int i = 0; fragments != null && i < fragments.length; i++) { |
| String location = fragments[i].getLocation(); |
| try { |
| URL locationURL = new URL(location); |
| locationURL = FileLocator.toFileURL(FileLocator.resolve(locationURL)); |
| list.add(asInstallRelativeURL(locationURL)); |
| } catch (IOException e) { |
| // skip bad fragments |
| } |
| } |
| } |
| return (URL[]) list.toArray(new URL[0]); |
| } |
| |
| /** |
| * Returns the path identifier for a plugin entry. |
| * <code>plugins/<pluginId>_<pluginVersion>.jar</code> |
| * @return the path identifier |
| */ |
| private String getPathID(IPluginEntry entry) { |
| return Site.DEFAULT_PLUGIN_PATH + entry.getVersionedIdentifier().toString() + FeatureContentProvider.JAR_EXTENSION; |
| } |
| |
| /** |
| * Try to recast URL as platform:/base/ |
| */ |
| private URL asInstallRelativeURL(URL url) { |
| // get location of install |
| URL install = ConfiguratorUtils.getInstallURL(); |
| |
| // try to determine if supplied URL can be recast as install-relative |
| if (install.getProtocol().equals(url.getProtocol())) { |
| if (install.getProtocol().equals("file")) { //$NON-NLS-1$ |
| String installS = new File(install.getFile()).getAbsolutePath().replace(File.separatorChar, '/'); |
| if (!installS.endsWith("/")) //$NON-NLS-1$ |
| installS += "/"; //$NON-NLS-1$ |
| String urlS = new File(url.getFile()).getAbsolutePath().replace(File.separatorChar, '/'); |
| if (!urlS.endsWith("/")) //$NON-NLS-1$ |
| urlS += "/"; //$NON-NLS-1$ |
| int ix = installS.lastIndexOf("/"); //$NON-NLS-1$ |
| if (ix != -1) { |
| installS = installS.substring(0, ix + 1); |
| if (urlS.startsWith(installS)) { |
| try { |
| return new URL("platform:/base/" + urlS.substring(installS.length())); //$NON-NLS-1$ |
| } catch (MalformedURLException e) { |
| } |
| } |
| } |
| } |
| } |
| return url; |
| } |
| |
| private boolean isDuplicateSite(File siteDirectory) { |
| IConfiguredSite[] sites = getConfiguredSites(); |
| URL fileURL; |
| try { |
| fileURL = siteDirectory.toURL(); |
| } catch (MalformedURLException e) { |
| return false; |
| } |
| for (int i = 0; i < sites.length; i++) { |
| URL url = sites[i].getSite().getURL(); |
| if (UpdateManagerUtils.sameURL(fileURL, url)) |
| return true; |
| } |
| return false; |
| } |
| |
| /* |
| * Returns the feature url relative to the site. |
| */ |
| private String getFeatureRelativeURL(IFeature feature) { |
| String url = feature.getURL().toExternalForm(); |
| String siteURL = feature.getSite().getURL().toExternalForm(); |
| // TODO fix this. toURL() returns file:/d:/eclipse/etc... wheareas the |
| // platform.asLocalURL() returns file:d:/eclipse/etc... (no leading / ) |
| // if (url.startsWith("file:/") && Platform.getOS().equals("win32")) |
| // url = "file:" + url.substring(6); |
| |
| if (url.startsWith(siteURL)) |
| return url.substring(siteURL.length()); |
| else |
| return url; |
| } |
| |
| /** |
| * @return true if restart is needed |
| */ |
| private boolean isRestartNeeded(IPlatformConfiguration runtimeConfig) { |
| |
| // First, create a map for faster lookups |
| Set newPluginsSet = null; |
| if (runtimeConfig instanceof PlatformConfiguration) { |
| newPluginsSet = ((PlatformConfiguration)runtimeConfig).getPluginPaths(); |
| // On windows, we will be doing case insensitive search as well, so lower it now |
| if (isWindows) { |
| String[] newPluginsSetArray = (String[])newPluginsSet.toArray( new String[newPluginsSet.size()]); |
| for (int i = 0; i < newPluginsSetArray.length; i++) { |
| newPluginsSet.add(newPluginsSetArray[i].toLowerCase()); |
| } |
| } |
| } else { |
| URL[] newBundlePaths = runtimeConfig.getPluginPath(); |
| newPluginsSet = new HashSet(newBundlePaths.length); |
| for (int i=0; i<newBundlePaths.length; i++) { |
| |
| String pluginLocation = newBundlePaths[i].getFile(); |
| newPluginsSet.add(pluginLocation); |
| // On windows, we will be doing case insensitive search as well, so lower it now |
| if (isWindows) |
| newPluginsSet.add(pluginLocation.toLowerCase()); |
| } |
| } |
| |
| |
| |
| Bundle[] oldBundles = UpdateCore.getPlugin().getBundleContext().getBundles(); |
| |
| int offset = ConfigurationActivator.UPDATE_PREFIX.length(); |
| for (int i=0; i<oldBundles.length; i++) { |
| if (oldBundles[i].getBundleId() == 0) |
| continue; // skip the system bundle |
| String oldBundleLocation = oldBundles[i].getLocation(); |
| // Don't worry about bundles we did not install |
| if (!oldBundleLocation.startsWith(ConfigurationActivator.UPDATE_PREFIX)) |
| continue; |
| oldBundleLocation = oldBundleLocation.substring(offset); |
| |
| if (newPluginsSet.contains(oldBundleLocation)) |
| continue; |
| if (isWindows && newPluginsSet.contains(oldBundleLocation.toLowerCase())) |
| continue; |
| |
| if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_CONFIGURATION) |
| UpdateCore.debug("Bundle " + oldBundleLocation + " has been removed"); //$NON-NLS-1$ //$NON-NLS-2$ |
| return true; |
| } |
| |
| if (runtimeConfig instanceof PlatformConfiguration) { |
| return areThereNewVersionOfOldPlugins( ((PlatformConfiguration)runtimeConfig).getPlugins(), oldBundles); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * The method should only be called if all old plug-ins exist in the new |
| * configuration. Determines if a new version was added to any plugin ID, so |
| * more versions are enabled for any given plug-in id then in old |
| * configuration. |
| * |
| * @param newConfigurationPlugins |
| * @param oldConfigurationBundles |
| * @return |
| */ |
| private boolean areThereNewVersionOfOldPlugins(PluginEntry[] newConfigurationPlugins, Bundle[] oldConfigurationBundles) { |
| |
| |
| for ( int i = 0; i < oldConfigurationBundles.length; i++) { |
| if (oldConfigurationBundles[i].getBundleId() == 0) |
| continue; // skip the system bundle |
| if ( getNumberOfPlugins(oldConfigurationBundles[i].getSymbolicName(), oldConfigurationBundles) != getNumberOfPlugins(oldConfigurationBundles[i].getSymbolicName(), newConfigurationPlugins)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| private int getNumberOfPlugins(String symbolicName, PluginEntry[] newConfigurationPlugins) { |
| |
| int numberOfPlugins = 0; |
| |
| for ( int i = 0; i < newConfigurationPlugins.length; i++) { |
| if ( symbolicName.equals(newConfigurationPlugins[i].getPluginIdentifier())) { |
| numberOfPlugins++; |
| } |
| } |
| |
| return numberOfPlugins; |
| } |
| |
| private int getNumberOfPlugins(String symbolicName, Bundle[] oldConfigurationBundles) { |
| |
| int numberOfPlugins = 0; |
| |
| for ( int i = 0; i < oldConfigurationBundles.length; i++) { |
| if ( symbolicName.equals(oldConfigurationBundles[i].getSymbolicName())) { |
| numberOfPlugins++; |
| } |
| } |
| |
| return numberOfPlugins; |
| } |
| |
| /* (non-Javadoc) |
| * @see java.lang.Object#equals(java.lang.Object) |
| */ |
| public boolean equals(Object obj) { |
| if (this == obj) |
| return true; |
| if (!(obj instanceof InstallConfiguration)) |
| return false; |
| |
| InstallConfiguration config = (InstallConfiguration)obj; |
| |
| return getCreationDate().equals(config.getCreationDate()) && |
| getLabel().equals(config.getLabel()) && |
| getLocationURLString().equals(config.getLocationURLString()); |
| } |
| } |