blob: e45688417431d10d3315a5a10792dcf70ac7feb9 [file] [log] [blame]
package org.eclipse.update.internal.core;
/*
* (c) Copyright IBM Corp. 2000, 2001.
* All Rights Reserved.
*/
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.TreeSet;
import org.eclipse.core.internal.boot.LaunchInfo;
import org.eclipse.core.internal.boot.LaunchInfo.VersionedIdentifier;
import org.eclipse.core.internal.boot.update.IComponentDescriptor;
import org.eclipse.core.internal.boot.update.IComponentEntryDescriptor;
import org.eclipse.core.internal.boot.update.IFragmentEntryDescriptor;
import org.eclipse.core.internal.boot.update.IInstallable;
import org.eclipse.core.internal.boot.update.IPluginEntryDescriptor;
import org.eclipse.core.internal.boot.update.IProductDescriptor;
import org.eclipse.core.internal.boot.update.IUMRegistry;
import org.eclipse.core.internal.boot.update.IURLNamePair;
import org.eclipse.core.internal.boot.update.LogStoreException;
import org.eclipse.core.internal.boot.update.UMEclipseTree;
import org.eclipse.core.internal.boot.update.UMRegistryManager;
import org.eclipse.core.internal.boot.update.UpdateManagerConstants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.update.internal.ui.JarVerificationService;
/**
* Update Manager updates a workstation in one of three modes:
* <ol>
* <li>local</li>
* <li>remote</li>
* <li>remote cached</li>
* </ol>
* Usage:
* <ol>
* <li>Create an instance of this class</li>
* <li>Set persistent properties as required</li>
* <ul>
* <li>mode</li>
* <li>update log URL</li>
* <li>history log URL</li>
* </ul>
* <li>Call the initialize function</li>
* <li>Call the update function</li>
* </ol>
* Persistent properties are loaded before any are changed, and saved after any
* are changed.
*/
public class UpdateManager {
// Package name for this class
// Used by UpdateManagerStrings to obtain its resource bundle properties file
//---------------------------------------------------------------------------
public static final String _strPackageName = "org.eclipse.update.internal.core";
public static UpdateManager _updateManagerInstance = null;
// Persistent properties
//----------------------
protected int _iMode = UpdateManagerConstants.MODE_LOCAL;
protected String _strUpdateLogURL = null;
protected String _strHistoryLogURL = null;
// Instance state data
//--------------------
protected UMRegistryManager _registryManager = null;
protected UMSessionManager _sessionManager = null;
protected Shell _shell = null;
protected JarVerificationService _jarVerifier = null;
/**
* Constructs an instance of this class, then initializes by loading its persistent properties
*/
public UpdateManager() {
}
/**
* Constructs an instance of this class, then initializes by loading its persistent properties
*/
public UpdateManager( Shell shell ) {
_updateManagerInstance = this;
_shell = shell;
}
/**
* Deletes all files in the staging area.
*/
public void cleanup() {
String strStagingDirectory = UMEclipseTree.getFileInPlatformString(UMEclipseTree.getStagingArea());
File fileStagingDirectory = new File(strStagingDirectory);
if (fileStagingDirectory.exists() == true) {
File[] files = fileStagingDirectory.listFiles();
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory() == true) {
cleanupDirectory(files[i]);
}
boolean bSuccessful = files[i].delete();
}
}
}
/**
*/
public static void cleanupDirectory(File fileDirectory) {
File[] files = fileDirectory.listFiles();
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory() == true) {
cleanupDirectory(files[i]);
}
boolean bSuccessful = files[i].delete();
// if (!bSuccessful)
// System.out.println("ooops!" + files[i]);
}
}
/**
*/
public UMSessionManagerSession createSession(IInstallable[] descriptors, boolean bVerifyJars) throws UpdateManagerException {
// FOR NOW DO NOT DO JAR VERIFICATION
//-----------------------------------
bVerifyJars = false;
// Create a new update session
//----------------------------
UMSessionManagerSession session = _sessionManager.createUpdateSession();
// Create a definer that can define the operations required
//---------------------------------------------------------
ISessionDefiner sessionDefiner = new UMSessionDefinerReferenceUpdate();
// Define a set of operations
//---------------------------
sessionDefiner.defineOperations(session, descriptors, bVerifyJars);
// Save the update log
//--------------------
try {
_sessionManager.saveUpdateLog();
}
catch (LogStoreException ex) {
throw new UpdateManagerException(ex.getMessage());
}
return session;
}
/**
* Updates the local machine by:
* <ol>
* <li>defining the operations</li>
* <li>downloading any new objects</li>
* <li>applying any downloaded updates</li>
* <li>displaying a progress monitor</li>
* </ol>
*/
public UMSessionManagerSession executeSession( UMSessionManagerSession session, IProgressMonitor progressMonitor ) throws UpdateManagerException {
// Throw any exception when complete
//----------------------------------
UpdateManagerException umException = null;
// Execute the session
//--------------------
_sessionManager.executeSession( session, progressMonitor );
// Move successful sessions from update log to history log
//--------------------------------------------------------
try {
_sessionManager.updateAndSaveLogs();
}
catch (LogStoreException ex) {
if (umException != null) {
umException = new UpdateManagerException("S_Unable_to_save_update_logs");
}
}
// Throw any exceptions found
//---------------------------
if (umException != null) {
throw umException;
}
return session;
}
/**
* Updates the local machine by:
* <ol>
* <li>defining the operations</li>
* <li>downloading any new objects</li>
* <li>applying any downloaded updates</li>
* <li>displaying a progress monitor</li>
* </ol>
*/
public UMSessionManagerSession executeSessionUndo( UMSessionManagerSession session, IProgressMonitor progressMonitor ) throws UpdateManagerException {
// Throw any exception when complete
//----------------------------------
UpdateManagerException umException = null;
// Execute the session
//--------------------
_sessionManager.executeSessionUndo( session, progressMonitor );
// Move successful sessions from update log to history log
//--------------------------------------------------------
try {
_sessionManager.updateAndSaveLogs();
}
catch (LogStoreException ex) {
if (umException != null) {
umException = new UpdateManagerException("S Unable to save update logs");
}
}
// Throw any exceptions found
//---------------------------
if (umException != null) {
throw umException;
}
return session;
}
/**
*/
public static UpdateManager getCurrentInstance() {
return _updateManagerInstance;
}
/**
* Takes a string with an Id + '_' + Version, and returns the Id.
*/
private String getIdFromInfoString(String strInfo) {
String strId = null;
int iIndex = strInfo.lastIndexOf('_');
if (iIndex >= 0) {
strId = strInfo.substring(0, iIndex);
}
else {
strId = strInfo;
}
return strId;
}
// return the jar verifier
public JarVerificationService getJarVerifier() {
if (_jarVerifier == null)
_jarVerifier = new JarVerificationService( _shell );
return _jarVerifier;
}
/**
* Returns a list of components that require updating by:
*<ol>
*<li>Loading all product/component manifests from .install/tree </li>
*<li>Determining which components require updating by:</li>
*<ol>
*<li>Collecting update URLs from each component</li>
*<li>Collecting update URLs from products that components are a part of</li>
*</ol>
*<li>Determining what updates are available by:</li>
*<ol>
*<li>Accessing the update URL</li>
*<li>Determining if the component is a newer version of the existing one</li>
*</ol>
*<li>
*</ol>
*/
public IURLNamePair[] getLocalDiscoveryURLs() {
IURLNamePair[] urlNPs = null;
// Obtain the local registry
//--------------------------
IUMRegistry registry = _registryManager.getLocalRegistry();
// Create a list of all URLs
//--------------------------
TreeSet setURLs = new TreeSet( new UpdateManagerURLComparator() );
// Obtain a list of all installed components
//------------------------------------------
IComponentDescriptor[] componentDescriptors = registry.getComponentDescriptors();
// Obtain a list of discovery URLs
//--------------------------------
for (int i = 0; i < componentDescriptors.length; ++i) {
urlNPs = componentDescriptors[i].getDiscoveryURLs();
for (int j = 0; j < urlNPs.length; ++j) {
setURLs.add(urlNPs[j]);
}
}
// Obtain a list of all installed products
//----------------------------------------
IProductDescriptor[] productDescriptors = registry.getProductDescriptors();
// Obtain a list of discovery URLs
//--------------------------------
for (int i = 0; i < productDescriptors.length; ++i) {
urlNPs = productDescriptors[i].getDiscoveryURLs();
for (int j = 0; j < urlNPs.length; ++j) {
setURLs.add(urlNPs[j]);
}
}
urlNPs = new IURLNamePair[ setURLs.size() ];
System.arraycopy(setURLs.toArray(), 0, urlNPs, 0, setURLs.size() );
return urlNPs;
}
/**
* Returns a list of components that require updating by:
*<ol>
*<li>Loading all product/component manifests from .install/tree </li>
*<li>Determining which components require updating by:</li>
*<ol>
*<li>Collecting update URLs from each component</li>
*<li>Collecting update URLs from products that components are a part of</li>
*</ol>
*<li>Determining what updates are available by:</li>
*<ol>
*<li>Accessing the update URL</li>
*<li>Determining if the component is a newer version of the existing one</li>
*</ol>
*<li>
*</ol>
*/
public IURLNamePair[] getLocalUpdateURLs() {
IURLNamePair[] urlNPs = null;
// Obtain the local registry
//--------------------------
IUMRegistry registry = _registryManager.getLocalRegistry();
// Create a list of all URLs
//--------------------------
TreeSet setURLs = new TreeSet( new UpdateManagerURLComparator() );
// Obtain a list of all installed components
//------------------------------------------
IComponentDescriptor[] componentDescriptors = registry.getComponentDescriptors();
// Obtain a list of discovery URLs
//--------------------------------
for (int i = 0; i < componentDescriptors.length; ++i) {
urlNPs = componentDescriptors[i].getUpdateURLs();
for (int j = 0; j < urlNPs.length; ++j) {
setURLs.add(urlNPs[j]);
}
}
// Obtain a list of all installed products
//----------------------------------------
IProductDescriptor[] productDescriptors = registry.getProductDescriptors();
// Obtain a list of discovery URLs
//--------------------------------
for (int i = 0; i < productDescriptors.length; ++i) {
urlNPs = productDescriptors[i].getUpdateURLs();
for (int j = 0; j < urlNPs.length; ++j) {
setURLs.add(urlNPs[j]);
}
}
urlNPs = new IURLNamePair[ setURLs.size() ];
System.arraycopy(setURLs.toArray(), 0, urlNPs, 0, setURLs.size() );
return urlNPs;
}
// return the local (current) registry
public IUMRegistry getRegistryAt(URL url) {
return _registryManager.getRegistryAt( url );
}
/**
*/
public UMRegistryManager getRegistryManager() {
return _registryManager;
}
/**
* Initializes the update and history log URLs,creates a session manager,
* and creates a registry manager.
*/
public void initialize() throws UpdateManagerException{
// Obtain install URL
//-------------------
URL urlBase = UMEclipseTree.getBaseInstallURL();
String strUrlBase = urlBase.toExternalForm();
String strUrlInstall = strUrlBase + "install/";
String strUrlUpdateLog = strUrlInstall + "update.log";
String strUrlHistoryLog = strUrlInstall + "history.log";
setUpdateLogURL(strUrlUpdateLog);
setHistoryLogURL(strUrlHistoryLog);
// Create a session manager
//-------------------------
try {
_sessionManager = new UMSessionManager(new URL(_strUpdateLogURL), new URL(_strHistoryLogURL), true);
}
catch (MalformedURLException ex) {
throw new UpdateManagerException("Invalid log URL specification");
}
catch (LogStoreException ex) {
throw new UpdateManagerException(ex.getMessage());
}
// Registry Manager
//-----------------
_registryManager = new UMRegistryManager(urlBase);
}
/**
*
*/
public void removeComponent(IComponentDescriptor componentDescriptor) {
removeComponent(componentDescriptor, null);
}
/**
*
*/
public void removeComponent(IComponentDescriptor componentDescriptor, IProductDescriptor productDescriptor) {
if( componentDescriptor == null )
return;
LaunchInfo launchInfo = LaunchInfo.getCurrent();
LaunchInfo.VersionedIdentifier vid = null;
// Plugins
//--------
IPluginEntryDescriptor[] pluginEntries = componentDescriptor.getPluginEntries();
for (int i = 0; i < pluginEntries.length; ++i) {
vid = new LaunchInfo.VersionedIdentifier(pluginEntries[i].getUniqueIdentifier(), pluginEntries[i].getVersionStr());
launchInfo.removePlugin(vid);
}
// Fragments
//----------
IFragmentEntryDescriptor[] fragmentEntries = componentDescriptor.getFragmentEntries();
for (int i = 0; i < fragmentEntries.length; ++i) {
vid = new LaunchInfo.VersionedIdentifier(fragmentEntries[i].getUniqueIdentifier(), pluginEntries[i].getVersionStr());
launchInfo.removeFragment(vid);
}
// Component
//----------
vid = new LaunchInfo.VersionedIdentifier(componentDescriptor.getUniqueIdentifier(), componentDescriptor.getVersionStr());
launchInfo.removeComponent(vid);
_registryManager.removeComponentDescriptorFromLocal(componentDescriptor, productDescriptor);
return;
}
/**
*
*/
public void removeProduct(IProductDescriptor productDescriptor) {
if( productDescriptor == null )
return;
// Components
//-----------
IComponentEntryDescriptor[] componentEntries = productDescriptor.getComponentEntries();
for (int i = 0; i < componentEntries.length; ++i) {
IComponentDescriptor componentDescriptor = componentEntries[i].getComponentDescriptor();
if (componentDescriptor.isRemovable(productDescriptor))
removeComponent(componentDescriptor, productDescriptor);
}
// Product
//--------
LaunchInfo.VersionedIdentifier vid = new LaunchInfo.VersionedIdentifier(productDescriptor.getUniqueIdentifier(), productDescriptor.getVersionStr());
LaunchInfo.getCurrent().removeConfiguration(vid);
_registryManager.removeProductDescriptorFromLocal(productDescriptor);
}
/**
* Sets the URL for the history log. This property is persistent.
*/
public void setHistoryLogURL(String strURL) throws UpdateManagerException {
// Check for valid URL
//--------------------
try {
new URL(strURL);
}
catch (MalformedURLException ex) {
throw new UpdateManagerException("Invalid log URL specification");
}
// Change the property
//--------------------
_strHistoryLogURL = strURL;
}
/**
* Sets the URL for the update log. This property is persistent.
*/
public void setUpdateLogURL(String strURL) throws UpdateManagerException {
// Check for valid URL
//--------------------
try {
new URL(strURL);
}
catch (MalformedURLException ex) {
throw new UpdateManagerException("Invalid log URL specification");
}
// Change the property
//--------------------
_strUpdateLogURL = strURL;
}
/**
* Updates the boot loader's launch information with what is currently installed.
*/
public void updateLaunchInfoAndRegistry(UMSessionManagerSession session) {
// Update launch info even if this session had a failure
// One or more parcels could have succeeded
//------------------------------------------------------
if (session != null) {
LaunchInfo launchInfo = LaunchInfo.getCurrent();
// Obtain product/component information
//-------------------------------------
UMSessionManagerParcel[] parcels = session.getParcels();
for (int i = 0; i < parcels.length; ++i) {
updateLaunchInfoAndRegistryParcel( parcels[i], launchInfo );
}
}
}
/**
* Recursively updates the boot loader's information for this parcel and sub-parcels.
*/
protected void updateLaunchInfoAndRegistryParcel(UMSessionManagerParcel parcel, LaunchInfo launchInfo) {
// Update the profile only if the install was successful
//------------------------------------------------------
if (parcel != null && parcel.getStatus().equals(UpdateManagerConstants.STATUS_SUCCEEDED) == true) {
Object objData = parcel.getData();
// Product
//--------
if (objData instanceof IProductDescriptor) {
updateLaunchInfoProduct((IProductDescriptor) objData, launchInfo);
_registryManager.addProductDescriptorToLocal((IProductDescriptor) objData);
}
// Component
//----------
else if (objData instanceof IComponentDescriptor) {
updateLaunchInfoComponent((IComponentDescriptor) objData, launchInfo);
_registryManager.addComponentDescriptorToLocal((IComponentDescriptor) objData, true);
}
// Component Entry
//----------------
else if (objData instanceof IComponentEntryDescriptor) {
IComponentDescriptor comp = ((IComponentEntryDescriptor)objData).getComponentDescriptor();
updateLaunchInfoComponent(comp, launchInfo);
_registryManager.addComponentDescriptorToLocal(comp, false);
}
// Do child parcels
//-----------------
UMSessionManagerParcel[] parcelChildren = parcel.getParcels();
for (int i = 0; i < parcelChildren.length; ++i) {
updateLaunchInfoAndRegistryParcel(parcelChildren[i], launchInfo);
}
}
}
/**
* Updates the boot loader's launch information with what is currently installed.
*/
public void updateLaunchInfoComponent(IComponentDescriptor descriptor, LaunchInfo launchInfo) {
// Component
//----------
launchInfo.setComponent(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(), descriptor.getVersionStr()));
// Plugins
//--------
IPluginEntryDescriptor[] pluginDescriptors = descriptor.getPluginEntries();
for (int i = 0; i < pluginDescriptors.length; ++i) {
updateLaunchInfoPlugin(pluginDescriptors[i], launchInfo);
}
// Fragments
//----------
IFragmentEntryDescriptor[] fragmentDescriptors = descriptor.getFragmentEntries();
for (int i = 0; i < fragmentDescriptors.length; ++i) {
updateLaunchInfoFragment(fragmentDescriptors[i], launchInfo);
}
}
/**
* Updates the boot loader's launch information with what is currently installed.
*/
public void updateLaunchInfoFragment(IFragmentEntryDescriptor descriptor, LaunchInfo launchInfo) {
launchInfo.setFragment(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()));
}
/**
* Updates the boot loader's launch information with what is currently installed.
*/
public void updateLaunchInfoPlugin(IPluginEntryDescriptor descriptor, LaunchInfo launchInfo) {
launchInfo.setPlugin(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()));
}
/**
* Updates the boot loader's launch information with what is currently installed.
*/
public void updateLaunchInfoProduct(IProductDescriptor descriptor, LaunchInfo launchInfo) {
launchInfo.setConfiguration(new LaunchInfo.VersionedIdentifier(descriptor.getUniqueIdentifier(),descriptor.getVersionStr()), descriptor.getApplication());
}
}