blob: 6a22b22f823a9ede5d81a5d8e9265883c3de711e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 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.equinox.internal.provisional.p2.ui.actions;
import java.util.*;
import org.eclipse.core.runtime.*;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.p2.ui.ProvUIMessages;
import org.eclipse.equinox.internal.p2.ui.model.AvailableUpdateElement;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.director.ProfileChangeRequest;
import org.eclipse.equinox.internal.provisional.p2.director.ProvisioningPlan;
import org.eclipse.equinox.internal.provisional.p2.engine.IProfile;
import org.eclipse.equinox.internal.provisional.p2.engine.ProvisioningContext;
import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.internal.provisional.p2.ui.*;
import org.eclipse.equinox.internal.provisional.p2.ui.dialogs.UpdateWizard;
import org.eclipse.equinox.internal.provisional.p2.ui.model.InstalledIUElement;
import org.eclipse.equinox.internal.provisional.p2.ui.operations.ProvisioningUtil;
import org.eclipse.equinox.internal.provisional.p2.ui.policy.IQueryProvider;
import org.eclipse.equinox.internal.provisional.p2.ui.policy.Policies;
import org.eclipse.equinox.internal.provisional.p2.ui.query.ElementQueryDescriptor;
import org.eclipse.equinox.internal.provisional.p2.updatechecker.UpdateEvent;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
public class UpdateAction extends ProfileModificationAction {
ArrayList allReplacements; // cache all the replacements found to seed the wizard
HashMap latestReplacements;
public UpdateAction(ISelectionProvider selectionProvider, String profileId, IProfileChooser chooser, Policies policies, Shell shell) {
super(ProvUI.UPDATE_COMMAND_LABEL, selectionProvider, profileId, chooser, policies, shell);
setToolTipText(ProvUI.UPDATE_COMMAND_TOOLTIP);
}
protected int performOperation(IInstallableUnit[] ius, String targetProfileId, ProvisioningPlan plan) {
// Caches should have been created while formulating the plan
Assert.isNotNull(latestReplacements);
Assert.isNotNull(allReplacements);
Assert.isNotNull(plan);
UpdateWizard wizard = new UpdateWizard(targetProfileId, ius, (AvailableUpdateElement[]) allReplacements.toArray(new AvailableUpdateElement[allReplacements.size()]), latestReplacements.values().toArray(), plan, getLicenseManager());
WizardDialog dialog = new WizardDialog(getShell(), wizard);
dialog.create();
PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), IProvHelpContextIds.UPDATE_WIZARD);
return dialog.open();
}
protected ProvisioningPlan getProvisioningPlan(IInstallableUnit[] ius, String targetProfileId, IProgressMonitor monitor) throws ProvisionException {
// Here we create a provisioning plan by finding the latest version available for any replacement.
// TODO to be smarter, we could check older versions if a new version made a plan invalid.
ArrayList toBeUpdated = new ArrayList();
latestReplacements = new HashMap();
allReplacements = new ArrayList();
for (int i = 0; i < ius.length; i++) {
UpdateEvent event = new UpdateEvent(targetProfileId, new IInstallableUnit[] {ius[i]});
ElementQueryDescriptor descriptor = getQueryProvider().getQueryDescriptor(event, IQueryProvider.AVAILABLE_UPDATES);
Iterator iter = descriptor.queryable.query(descriptor.query, descriptor.collector, null).iterator();
if (iter.hasNext())
toBeUpdated.add(ius[i]);
ArrayList currentReplacements = new ArrayList();
while (iter.hasNext()) {
IInstallableUnit iu = (IInstallableUnit) ProvUI.getAdapter(iter.next(), IInstallableUnit.class);
if (iu != null) {
AvailableUpdateElement element = new AvailableUpdateElement(iu, ius[i], targetProfileId);
currentReplacements.add(element);
allReplacements.add(element);
}
}
for (int j = 0; j < currentReplacements.size(); j++) {
AvailableUpdateElement replacementElement = (AvailableUpdateElement) currentReplacements.get(j);
AvailableUpdateElement latestElement = (AvailableUpdateElement) latestReplacements.get(replacementElement.getIU().getId());
IInstallableUnit latestIU = latestElement == null ? null : latestElement.getIU();
if (latestIU == null || replacementElement.getIU().getVersion().compareTo(latestIU.getVersion()) > 0)
latestReplacements.put(replacementElement.getIU().getId(), replacementElement);
}
}
if (toBeUpdated.size() <= 0) {
return new ProvisioningPlan(new Status(IStatus.INFO, ProvUIActivator.PLUGIN_ID, IStatusCodes.NOTHING_TO_UPDATE, ProvUIMessages.UpdateOperation_NothingToUpdate, null));
}
ProfileChangeRequest request = ProfileChangeRequest.createByProfileId(targetProfileId);
Iterator iter = toBeUpdated.iterator();
while (iter.hasNext())
request.removeInstallableUnits(new IInstallableUnit[] {(IInstallableUnit) iter.next()});
iter = latestReplacements.values().iterator();
while (iter.hasNext())
request.addInstallableUnits(new IInstallableUnit[] {((AvailableUpdateElement) iter.next()).getIU()});
ProvisioningPlan plan = ProvisioningUtil.getProvisioningPlan(request, new ProvisioningContext(), monitor);
return plan;
}
protected boolean isEnabledFor(Object[] selectionArray) {
Object parent = null;
// We cache the profile for performance reasons rather than get it for
// each IU. Note that below we reject any selection
// with different parents, so if there were IU's selected from multiple
// profiles, we catch this case and disable the action.
IProfile profile = getProfile(false);
if (profile == null)
return false;
if (selectionArray.length > 0) {
for (int i = 0; i < selectionArray.length; i++) {
if (selectionArray[i] instanceof InstalledIUElement) {
InstalledIUElement element = (InstalledIUElement) selectionArray[i];
int lock = getLock(profile, element.getIU());
if ((lock & IInstallableUnit.LOCK_UPDATE) == IInstallableUnit.LOCK_UPDATE)
return false;
if (parent == null) {
parent = element.getParent(null);
} else if (parent != element.getParent(null)) {
return false;
}
} else {
return false;
}
}
return true;
}
return false;
}
protected String getTaskName() {
return ProvUIMessages.UpdateIUProgress;
}
}