blob: f065189ba04bb8f278b4b18b0652be79b691142d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 WindRiver 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:
* WindRiver Corporation - initial API and implementation
* IBM Corporation - Ongoing development
* Ericsson AB (Pascal Rapicault) - Bug 387115 - Allow to export everything
* Ericsson AB (Hamdan Msheik) - Bug 398833, 402560
*******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.sdk.scheduler.migration;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.*;
import java.util.List;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.core.runtime.preferences.*;
import org.eclipse.equinox.internal.p2.metadata.query.UpdateQuery;
import org.eclipse.equinox.internal.p2.ui.ProvUI;
import org.eclipse.equinox.internal.p2.ui.ProvUIActivator;
import org.eclipse.equinox.internal.p2.ui.dialogs.*;
import org.eclipse.equinox.internal.p2.ui.model.*;
import org.eclipse.equinox.internal.p2.ui.sdk.scheduler.AutomaticUpdatePlugin;
import org.eclipse.equinox.internal.p2.ui.viewers.*;
import org.eclipse.equinox.p2.core.IProvisioningAgent;
import org.eclipse.equinox.p2.engine.*;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.query.*;
import org.eclipse.equinox.p2.repository.artifact.IArtifactRepositoryManager;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.dialogs.FilteredTree;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.progress.DeferredTreeContentManager;
import org.eclipse.ui.progress.WorkbenchJob;
import org.eclipse.ui.statushandlers.StatusManager;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
public class MigrationPage extends WizardPage implements ISelectableIUsPage, Listener {
protected String currentMessage;
// protected Button destinationBrowseButton;
protected CheckboxTreeViewer viewer = null;
protected Exception finishException;
protected boolean entryChanged = false;
protected static IProfileRegistry profileRegistry = null;
static IProvisioningAgent agent = null;
protected Button updateToLatest;
public static final String REMIND_ME_LATER = "remindMeToMigrateLater";
IProfile profile = null;
private ProvisioningOperationWizard wizard;
private ProvisioningUI ui;
protected IProvisioningAgent otherInstanceAgent = null;
private Collection<IInstallableUnit> unitsToMigrate;
private IProfile toImportFrom = null;
// private File instancePath = null;
private URI[] metaURIs = null;
private URI[] artiURIs = null;
/**
* {@link DelayedFilterCheckboxTree} has a timing bug to prevent restoring the check state,
* the methods {@link DeferredTreeContentManager}'s runClearPlaceholderJob and
* DelayedFilterCheckboxTree.doCreateRefreshJob().new JobChangeAdapter() {...}.done(IJobChangeEvent) has timing issue,
* I can't find a way to guarantee the first job is executed firstly
*
*/
final class ImportExportFilteredTree extends FilteredTree {
ArrayList<Object> checkState = new ArrayList<Object>();
ImportExportFilteredTree(Composite parent, int treeStyle, PatternFilter filter, boolean useNewLook) {
super(parent, treeStyle, filter, useNewLook);
}
@Override
protected TreeViewer doCreateTreeViewer(Composite composite, int style) {
return new CheckboxTreeViewer(composite, style);
}
@Override
protected WorkbenchJob doCreateRefreshJob() {
WorkbenchJob job = super.doCreateRefreshJob();
job.addJobChangeListener(new JobChangeAdapter() {
@Override
public void aboutToRun(IJobChangeEvent event) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
Object[] checked = viewer.getCheckedElements();
if (checkState == null)
checkState = new ArrayList<Object>(checked.length);
for (int i = 0; i < checked.length; i++)
if (!viewer.getGrayed(checked[i]))
if (!checkState.contains(checked[i]))
checkState.add(checked[i]);
}
});
}
@Override
public void done(IJobChangeEvent event) {
if (event.getResult().isOK()) {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
if (viewer == null || viewer.getTree().isDisposed())
return;
if (checkState == null)
return;
viewer.setCheckedElements(new Object[0]);
viewer.setGrayedElements(new Object[0]);
// Now we are only going to set the check state of the leaf nodes
// and rely on our container checked code to update the parents properly.
Iterator<Object> iter = checkState.iterator();
while (iter.hasNext()) {
viewer.setChecked(iter.next(), true);
}
updatePageCompletion();
}
});
}
}
});
return job;
}
}
class TreeViewerComparator extends ViewerComparator {
private int sortColumn = 0;
private int lastSortColumn = 0;
private boolean ascending = false;
private boolean lastAscending = false;
@Override
public int compare(Viewer viewer1, Object e1, Object e2) {
IInstallableUnit iu1 = ProvUI.getAdapter(e1, IInstallableUnit.class);
IInstallableUnit iu2 = ProvUI.getAdapter(e2, IInstallableUnit.class);
if (iu1 != null && iu2 != null) {
if (viewer1 instanceof TreeViewer) {
TreeViewer treeViewer = (TreeViewer) viewer1;
IBaseLabelProvider baseLabel = treeViewer.getLabelProvider();
if (baseLabel instanceof ITableLabelProvider) {
ITableLabelProvider tableProvider = (ITableLabelProvider) baseLabel;
String e1p = tableProvider.getColumnText(e1, getSortColumn());
String e2p = tableProvider.getColumnText(e2, getSortColumn());
// don't suppress this warning as it will cause build-time warning
// see bug 423628. This should be possible to fix once
// SWT/JFace adopts generics
int result = getComparator().compare(e1p, e2p);
// Secondary column sort
if (result == 0) {
e1p = tableProvider.getColumnText(e1, lastSortColumn);
e2p = tableProvider.getColumnText(e2, lastSortColumn);
// don't suppress this warning as it will cause build-time warning
// see bug 423628. This should be possible to fix once
// SWT/JFace adopts generics
int result2 = getComparator().compare(e1p, e2p);
return lastAscending ? result2 : (-1) * result2;
}
return isAscending() ? result : (-1) * result;
}
}
// we couldn't determine a secondary sort, call it equal
return 0;
}
return super.compare(viewer1, e1, e2);
}
/**
* @return Returns the sortColumn.
*/
public int getSortColumn() {
return sortColumn;
}
/**
* @param sortColumn
* The sortColumn to set.
*/
public void setSortColumn(int sortColumn) {
if (this.sortColumn != sortColumn) {
lastSortColumn = this.sortColumn;
lastAscending = this.ascending;
this.sortColumn = sortColumn;
}
}
/**
* @return Returns the ascending.
*/
public boolean isAscending() {
return ascending;
}
/**
* @param ascending
* The ascending to set.
*/
public void setAscending(boolean ascending) {
this.ascending = ascending;
}
}
static {
BundleContext context = Platform.getBundle(ProvUIActivator.PLUGIN_ID).getBundleContext();
ServiceTracker<IProvisioningAgent, IProvisioningAgent> tracker = new ServiceTracker<IProvisioningAgent, IProvisioningAgent>(context, IProvisioningAgent.class, null);
tracker.open();
agent = tracker.getService();
tracker.close();
if (agent != null)
profileRegistry = (IProfileRegistry) agent.getService(IProfileRegistry.SERVICE_NAME);
}
public MigrationPage(String pageName) {
super(pageName);
}
public MigrationPage(ProvisioningUI ui, ProvisioningOperationWizard wizard, IProfile toImportFrom, Collection<IInstallableUnit> unitsToMigrate, boolean firstTime) {
super("MigrationPageInstance"); //$NON-NLS-1$
this.wizard = wizard;
this.ui = ui;
profile = getSelfProfile();
this.toImportFrom = toImportFrom;
this.unitsToMigrate = unitsToMigrate;
setTitle(firstTime ? ProvUIMessages.MigrationPage_DIALOG_TITLE_FIRSTRUN : ProvUIMessages.MigrationPage_DIALOG_TITLE);
setDescription(NLS.bind(ProvUIMessages.MigrationPage_DIALOG_DESCRIPTION, Platform.getProduct().getName()));
}
public MigrationPage(ProvisioningUI ui, ProvisioningOperationWizard wizard, boolean firstTime) {
super("importfrominstancepage"); //$NON-NLS-1$
this.wizard = wizard;
this.ui = ui;
setTitle(firstTime ? ProvUIMessages.MigrationPage_DIALOG_TITLE_FIRSTRUN : ProvUIMessages.MigrationPage_DIALOG_TITLE);
setDescription(NLS.bind(ProvUIMessages.MigrationPage_DIALOG_DESCRIPTION, Platform.getProduct().getName()));
}
protected IProfile getSelfProfile() {
if (profileRegistry != null) {
String selfID = System.getProperty("eclipse.p2.profile"); //$NON-NLS-1$
if (selfID == null)
selfID = IProfileRegistry.SELF;
return profileRegistry.getProfile(selfID);
}
return null;
}
private void createColumns(TreeViewer treeViewer) {
String[] titles = {ProvUIMessages.Column_Name, ProvUIMessages.Column_Version, ProvUIMessages.Column_Id};
for (int i = 0; i < titles.length; i++) {
TreeViewerColumn column = new TreeViewerColumn(treeViewer, SWT.NONE);
column.getColumn().setText(titles[i]);
column.getColumn().setResizable(true);
column.getColumn().setMoveable(true);
if (titles[i].equals(ProvUIMessages.Column_Name)) {
column.getColumn().setWidth(300);
} else {
column.getColumn().setWidth(200);
}
if (ProvUIMessages.Column_Name.equals(titles[i]))
updateTableSorting(i);
final int columnIndex = i;
column.getColumn().addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateTableSorting(columnIndex);
}
});
}
}
protected void updateTableSorting(int columnIndex) {
TreeViewerComparator comparator = (TreeViewerComparator) viewer.getComparator();
// toggle direction if it's the same column
if (columnIndex == comparator.getSortColumn()) {
comparator.setAscending(!comparator.isAscending());
}
comparator.setSortColumn(columnIndex);
viewer.getTree().setSortColumn(viewer.getTree().getColumn(columnIndex));
viewer.getTree().setSortDirection(comparator.isAscending() ? SWT.UP : SWT.DOWN);
viewer.refresh(false);
}
public void createControl(Composite parent) {
initializeDialogUnits(parent);
// initializeService();
Composite composite = new Composite(parent, SWT.NULL);
GridLayout layout = new GridLayout(1, true);
layout.horizontalSpacing = 0;
layout.verticalSpacing = 5;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL));
createContents(composite);
// can not finish initially, but don't want to start with an error
// message either
if (!(validateOptionsGroup())) {
setPageComplete(false);
}
setControl(composite);
// giveFocusToDestination();
Dialog.applyDialogFont(composite);
}
protected IUColumnConfig[] getColumnConfig() {
return new IUColumnConfig[] {new IUColumnConfig(org.eclipse.equinox.internal.p2.ui.ProvUIMessages.ProvUI_NameColumnTitle, IUColumnConfig.COLUMN_NAME, ILayoutConstants.DEFAULT_PRIMARY_COLUMN_WIDTH), new IUColumnConfig(org.eclipse.equinox.internal.p2.ui.ProvUIMessages.ProvUI_VersionColumnTitle, IUColumnConfig.COLUMN_VERSION, ILayoutConstants.DEFAULT_SMALL_COLUMN_WIDTH), new IUColumnConfig(org.eclipse.equinox.internal.p2.ui.ProvUIMessages.ProvUI_IdColumnTitle, IUColumnConfig.COLUMN_ID, ILayoutConstants.DEFAULT_COLUMN_WIDTH)};
}
protected void createContents(Composite composite) {
createInstallationTable(composite);
createAdditionOptions(composite);
}
protected void createInstallationTable(final Composite parent) {
SashForm sashForm = new SashForm(parent, SWT.VERTICAL);
FillLayout fill = new FillLayout();
sashForm.setLayout(fill);
GridData data = new GridData(GridData.FILL_BOTH);
sashForm.setLayoutData(data);
Composite sashComposite = new Composite(sashForm, SWT.NONE);
GridLayout grid = new GridLayout();
grid.marginWidth = 0;
grid.marginHeight = 0;
sashComposite.setLayout(grid);
PatternFilter filter = getPatternFilter();
filter.setIncludeLeadingWildcard(true);
final ImportExportFilteredTree filteredTree = new ImportExportFilteredTree(sashComposite, SWT.MULTI | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, filter, true);
viewer = (CheckboxTreeViewer) filteredTree.getViewer();
final Tree tree = viewer.getTree();
tree.setHeaderVisible(true);
tree.setLinesVisible(false);
GridData treeDataGrid = new GridData(GridData.FILL_BOTH);
treeDataGrid.heightHint = convertHeightInCharsToPixels(ILayoutConstants.DEFAULT_TABLE_HEIGHT);
treeDataGrid.widthHint = convertWidthInCharsToPixels(ILayoutConstants.DEFAULT_TABLE_WIDTH);
tree.setLayoutData(treeDataGrid);
viewer.setComparator(new TreeViewerComparator());
viewer.setComparer(new ProvElementComparer());
createColumns(viewer);
final ITreeContentProvider contentProvider = getContentProvider();
viewer.setContentProvider(contentProvider);
viewer.setLabelProvider(getLabelProvider());
viewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
if (!event.getChecked() && filteredTree.checkState != null) {
ArrayList<Object> toRemove = new ArrayList<Object>(1);
// See bug 258117. Ideally we would get check state changes
// for children when the parent state changed, but we aren't, so
// we need to remove all children from the additive check state
// cache.
if (contentProvider.hasChildren(event.getElement())) {
Set<Object> unchecked = new HashSet<Object>();
Object[] children = contentProvider.getChildren(event.getElement());
for (int i = 0; i < children.length; i++) {
unchecked.add(children[i]);
}
Iterator<Object> iter = filteredTree.checkState.iterator();
while (iter.hasNext()) {
Object current = iter.next();
if (current != null && unchecked.contains(current)) {
toRemove.add(current);
}
}
} else {
for (Object element : filteredTree.checkState) {
if (viewer.getComparer().equals(element, event.getElement())) {
toRemove.add(element);
// Do not break out of the loop. We may have duplicate equal
// elements in the cache. Since the cache is additive, we want
// to be sure we've gotten everything.
}
}
}
filteredTree.checkState.removeAll(toRemove);
}
}
});
parent.addControlListener(new ControlAdapter() {
private final int[] columnRate = new int[] {6, 2, 2};
@Override
public void controlResized(ControlEvent e) {
Rectangle area = parent.getClientArea();
Point size = tree.computeSize(SWT.DEFAULT, SWT.DEFAULT);
ScrollBar vBar = tree.getVerticalBar();
int width = area.width - tree.computeTrim(0, 0, 0, 0).width - vBar.getSize().x;
if (size.y > area.height + tree.getHeaderHeight()) {
// Subtract the scrollbar width from the total column width
// if a vertical scrollbar will be required
Point vBarSize = vBar.getSize();
width -= vBarSize.x;
}
Point oldSize = tree.getSize();
TreeColumn[] columns = tree.getColumns();
int hasUsed = 0, i = 0;
if (oldSize.x > area.width) {
// table is getting smaller so make the columns
// smaller first and then resize the table to
// match the client area width
for (; i < columns.length - 1; i++) {
columns[i].setWidth(width * columnRate[i] / 10);
hasUsed += columns[i].getWidth();
}
columns[columns.length - 1].setWidth(width - hasUsed);
tree.setSize(area.width, area.height);
} else {
// table is getting bigger so make the table
// bigger first and then make the columns wider
// to match the client area width
tree.setSize(area.width, area.height);
for (; i < columns.length - 1; i++) {
columns[i].setWidth(width * columnRate[i] / 10);
hasUsed += columns[i].getWidth();
}
columns[columns.length - 1].setWidth(width - hasUsed);
}
}
});
ICheckStateProvider provider = getViewerDefaultState();
if (provider != null)
viewer.setCheckStateProvider(provider);
else
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
updatePageCompletion();
}
});
viewer.getControl().setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
viewer.setInput(getInput());
viewer.getTree().addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.CHECK) {
if (hasInstalled(ProvUI.getAdapter(event.item.getData(), IInstallableUnit.class))) {
viewer.getTree().setRedraw(false);
((TreeItem) event.item).setChecked(false);
viewer.getTree().setRedraw(true);
}
}
updatePageCompletion();
}
});
Composite buttons = new Composite(sashComposite, SWT.NONE);
buttons.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
buttons.setLayout(new RowLayout(SWT.HORIZONTAL));
Button selectAll = new Button(buttons, SWT.PUSH);
selectAll.setText(ProvUIMessages.AbstractPage_ButtonSelectAll);
selectAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
for (TreeItem item : viewer.getTree().getItems()) {
if (!item.getChecked()) {
item.setChecked(true);
Event event = new Event();
event.widget = item.getParent();
event.detail = SWT.CHECK;
event.item = item;
event.type = SWT.Selection;
viewer.getTree().notifyListeners(SWT.Selection, event);
}
}
updatePageCompletion();
}
});
Button deselectAll = new Button(buttons, SWT.PUSH);
deselectAll.setText(ProvUIMessages.AbstractPage_ButtonDeselectAll);
deselectAll.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
for (TreeItem item : viewer.getTree().getItems()) {
viewer.setSubtreeChecked(item.getData(), false);
}
updatePageCompletion();
}
});
}
protected void createAdditionOptions(Composite parent) {
Composite composite = new Composite(parent, SWT.BORDER);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
updateToLatest = new Button(composite, SWT.CHECK);
updateToLatest.setText(ProvUIMessages.MigrationPage_UPDATE_TO_LATEST);
updateToLatest.setSelection(loadCustomizedSetting());
}
protected PatternFilter getPatternFilter() {
return new AvailableIUPatternFilter(getColumnConfig());
}
protected ICheckStateProvider getViewerDefaultState() {
return new ICheckStateProvider() {
public boolean isGrayed(Object element) {
return false;
}
public boolean isChecked(Object element) {
if (profile != null) {
IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class);
IQueryResult<IInstallableUnit> collector = profile.query(QueryUtil.createIUQuery(iu.getId(), new VersionRange(iu.getVersion(), true, null, false)), new NullProgressMonitor());
if (collector.isEmpty()) {
return true;
}
}
return false;
}
};
}
// protected ITableLabelProvider getLabelProvider() {
// return new IUDetailsLabelProvider(null, getColumnConfig(), null);
// }
protected ITreeContentProvider getContentProvider() {
ProvElementContentProvider provider = new ProvElementContentProvider() {
@Override
public boolean hasChildren(Object element) {
if (element instanceof InstalledIUElement)
return false;
return super.hasChildren(element);
}
@Override
public Object[] getChildren(Object parent) {
if (parent instanceof InstalledIUElement)
return new Object[0];
return super.getChildren(parent);
}
};
return provider;
}
protected boolean determinePageCompletion() {
currentMessage = null;
// validate groups in order of priority so error message is the most important one
boolean complete = validateOptionsGroup();
// Avoid draw flicker by not clearing the error
// message unless all is valid.
if (complete) {
setErrorMessage(null);
} else {
setErrorMessage(currentMessage);
}
return complete;
}
protected int getBrowseDialogStyle() {
return SWT.OPEN;
}
//TODO remove the implementation of Listener
public void handleEvent(Event event) {
// Widget source = event.widget;
//
// if (source == destinationBrowseButton) {
// handleDestinationBrowseButtonPressed();
// }
// updatePageCompletion();
}
/**
* Determine if the page is complete and update the page appropriately.
*/
protected void updatePageCompletion() {
boolean pageComplete = determinePageCompletion();
setPageComplete(pageComplete);
if (pageComplete) {
// if (this instanceof AbstractImportPage_c)
// saveWidgetValues();
setMessage(null);
}
}
protected boolean validateOptionsGroup() {
if (viewer == null || viewer.getCheckedElements().length > 0)
return true;
currentMessage = getNoOptionsMessage();
return false;
}
protected ProvisioningOperationWizard getProvisioningWizard() {
return wizard;
}
protected ProvisioningUI getProvisioningUI() {
return ui;
}
public boolean hasInstalled(IInstallableUnit iu) {
IQueryResult<IInstallableUnit> results = profile.query(QueryUtil.createIUQuery(iu.getId(), new VersionRange(iu.getVersion(), true, null, false)), null);
return !results.isEmpty();
}
public String getIUNameWithDetail(IInstallableUnit iu) {
IQueryResult<IInstallableUnit> results = profile.query(QueryUtil.createIUQuery(iu.getId(), new VersionRange(iu.getVersion(), true, null, false)), null);
String text = iu.getProperty(IProfile.PROP_NAME, null);
text = (text != null) ? text : iu.getId();
if (!results.isEmpty()) {
boolean hasHigherVersion = false;
boolean hasEqualVersion = false;
for (IInstallableUnit installedIU : results.toSet()) {
int compareValue = installedIU.getVersion().compareTo(iu.getVersion());
if (compareValue > 0) {
hasHigherVersion = true;
break;
} else if (compareValue == 0)
hasEqualVersion = true;
}
if (hasHigherVersion)
return NLS.bind(ProvUIMessages.AbstractImportPage_HigherVersionInstalled, text);
else if (hasEqualVersion)
return NLS.bind(ProvUIMessages.AbstractImportPage_SameVersionInstalled, text);
}
return text;
}
protected void doFinish() throws Exception {
// do nothing
}
@Override
public boolean canFlipToNextPage() {
return isPageComplete();
}
protected String getDialogTitle() {
return ProvUIMessages.MigrationPage_DIALOG_TITLE;
}
protected Object getInput() {
IUElementListRoot root = new IUElementListRoot();
List<AvailableIUElement> elements = new ArrayList<AvailableIUElement>(unitsToMigrate.size());
for (IInstallableUnit unit : unitsToMigrate) {
elements.add(new AvailableIUElement(root, unit, toImportFrom.getProfileId(), false));
}
root.setChildren(elements.toArray());
return root;
}
protected String getInvalidDestinationMessage() {
return "";//ProvUIMessages.ImportFromInstallationPage_INVALID_DESTINATION; //$NON-NLS-1$
}
protected String getNoOptionsMessage() {
return ProvUIMessages.MigrationPage_SELECT_COMPONENT;
}
class ImportFromInstallationLabelProvider extends IUDetailsLabelProvider {
@Override
public String getColumnText(Object element, int columnIndex) {
String text = super.getColumnText(element, columnIndex);
// it's the order of label provider
if (columnIndex == 0) {
IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class);
return getIUNameWithDetail(iu);
}
return text;
}
@Override
public Color getForeground(Object element) {
IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class);
if (hasInstalled(iu))
return Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
return super.getForeground(element);
}
}
protected ITableLabelProvider getLabelProvider() {
return new ImportFromInstallationLabelProvider();
}
@Override
public void dispose() {
super.dispose();
if (otherInstanceAgent != null) {
otherInstanceAgent.stop();
otherInstanceAgent = null;
toImportFrom = null;
}
cleanLocalRepository();
}
public void cleanLocalRepository() {
if (metaURIs != null && metaURIs.length > 0) {
IProvisioningAgent runningAgent = getProvisioningUI().getSession().getProvisioningAgent();
IMetadataRepositoryManager manager = (IMetadataRepositoryManager) runningAgent.getService(IMetadataRepositoryManager.SERVICE_NAME);
for (URI uri : metaURIs)
manager.removeRepository(uri);
IArtifactRepositoryManager artifactManager = (IArtifactRepositoryManager) runningAgent.getService(IArtifactRepositoryManager.SERVICE_NAME);
for (URI uri : artiURIs)
artifactManager.removeRepository(uri);
}
}
// Both checkedElements and checkedElementsUpdates and the logic inside the getCheckedIUElements method
// are used to prevent unnecessary call to getUpdates method due to computational cost.
@SuppressWarnings("rawtypes")
private Set checkedElements;
@SuppressWarnings("rawtypes")
private Set checkedElementsUpdates;
private boolean getUpdatesCanceled;
public Object[] getCheckedIUElements() {
if (isUpdateToLatest()) {
Object[] latestUpdates = getLatestVersionOfCheckedElements();
// If the getUpdades operation is cancelled, then set checkedElements and checkedElementsUpdates to null to force the lookup for updates again. Thereafter throw OperationCanceledException.
if (getUpdatesCanceled) {
this.checkedElements = null;
this.checkedElementsUpdates = null;
throw new OperationCanceledException();
}
return latestUpdates;
}
return viewer.getCheckedElements();
}
@SuppressWarnings({"rawtypes", "unchecked"})
private Object[] getLatestVersionOfCheckedElements() {
Object[] checkedArray = viewer.getCheckedElements();
if (this.checkedElements == null) {
// initialize checkedElements and checkedElementsUpdates for the first time
this.checkedElements = new HashSet(Arrays.asList(checkedArray));
this.checkedElementsUpdates = new HashSet(Arrays.asList(getUpdates(checkedArray)));
} else {
Set checkedElementsNow = new HashSet(Arrays.asList(checkedArray));
if (checkedElementsNow.size() != this.checkedElements.size() || (!checkedElementsNow.containsAll(checkedElements))) {
// only if the set of checkedElements has changed get the update for them
this.checkedElements = checkedElementsNow; //
this.checkedElementsUpdates = new HashSet(Arrays.asList(getUpdates(checkedArray)));
}
}
return this.checkedElementsUpdates.toArray();
}
public Object[] getSelectedIUElements() {
// TODO Auto-generated method stub
return null;
}
public void setCheckedElements(Object[] elements) {
new UnsupportedOperationException();
}
// Look for update of the current selected installation units and replace the old ons with the updated version
private Object[] getUpdates(final Object[] _checkedElements) {
final Collection<IInstallableUnit> toInstall = new ArrayList<IInstallableUnit>();
try {
getContainer().run(false, true, new IRunnableWithProgress() {
public void run(IProgressMonitor monitor) {
SubMonitor sub = SubMonitor.convert(monitor, _checkedElements.length);
ProvisioningContext context = new ProvisioningContext(getProvisioningUI().getSession().getProvisioningAgent());
for (Object iu : _checkedElements) {
if (sub.isCanceled()) {
MigrationPage.this.getUpdatesCanceled = true;
toInstall.clear();
sub.done();
return;
}
if (iu instanceof AvailableIUElement) {
IInstallableUnit unit = ((AvailableIUElement) iu).getIU();
IuUpdateAndPatches updateAndPatches = filterToInstall(unit, updatesFor(unit, context, sub.newChild(1)));
if (updateAndPatches.update != null) {
toInstall.add(updateAndPatches.update);
} else {
toInstall.add(updateAndPatches.iu); // because it is not yet installed
toInstall.addAll(updateAndPatches.patches);
}
}
sub.worked(1);
}
}
});
} catch (InterruptedException e) {
// Nothing to report if thread was interrupted
} catch (InvocationTargetException e) {
ProvUI.handleException(e.getCause(), null, StatusManager.SHOW | StatusManager.LOG);
}
return toInstall.toArray();
}
public boolean isUpdateToLatest() {
return updateToLatest.getSelection();
}
public ProvisioningContext getProvisioningContext() {
ProvisioningContext context = new ProvisioningContext(getProvisioningUI().getSession().getProvisioningAgent());
context.setArtifactRepositories(artiURIs);
context.setMetadataRepositories(metaURIs);
return context;
}
private static boolean hasHigherFidelity(IInstallableUnit iu, IInstallableUnit currentIU) {
if (Boolean.valueOf(currentIU.getProperty(IInstallableUnit.PROP_PARTIAL_IU)).booleanValue() && !Boolean.valueOf(iu.getProperty(IInstallableUnit.PROP_PARTIAL_IU)).booleanValue())
return true;
return false;
}
public Collection<IInstallableUnit> updatesFor(IInstallableUnit toUpdate, ProvisioningContext context, IProgressMonitor monitor) {
// IPlanner planner = (IPlanner) getProvisioningUI().getSession().getProvisioningAgent().getService(IPlanner.SERVICE_NAME);
// return planner.updatesFor(toUpdate, context, monitor).toSet();
Map<String, IInstallableUnit> resultsMap = new HashMap<String, IInstallableUnit>();
SubMonitor sub = SubMonitor.convert(monitor, 1000);
IQueryable<IInstallableUnit> queryable = context.getMetadata(sub.newChild(500));
IQueryResult<IInstallableUnit> matches = queryable.query(new UpdateQuery(toUpdate), sub.newChild(500));
for (Iterator<IInstallableUnit> it = matches.iterator(); it.hasNext();) {
IInstallableUnit iu = it.next();
String key = iu.getId() + "_" + iu.getVersion().toString(); //$NON-NLS-1$
IInstallableUnit currentIU = resultsMap.get(key);
if (currentIU == null || hasHigherFidelity(iu, currentIU))
resultsMap.put(key, iu);
}
sub.done();
return resultsMap.values();
}
class IuUpdateAndPatches {
public IInstallableUnit iu;
public IInstallableUnit update;
public Collection<IInstallableUnit> patches;
IuUpdateAndPatches(IInstallableUnit iu) {
this.iu = iu;
this.patches = new ArrayList<IInstallableUnit>();
}
}
/**
*
* @param iu original unit.
* @param updates list of updates: patches or true updates.
* @return a structure holding the original unit, its most recent update and any available patches.
*/
private IuUpdateAndPatches filterToInstall(IInstallableUnit iu, Collection<IInstallableUnit> updates) {
IuUpdateAndPatches updateAndPatches = new IuUpdateAndPatches(iu);
for (IInstallableUnit update : updates) {
if (QueryUtil.isPatch(update)) {
updateAndPatches.patches.add(update);
} else {
if (updateAndPatches.update == null || updateAndPatches.update.getVersion().compareTo(update.getVersion()) < 0) {
updateAndPatches.update = update;
}
}
}
return updateAndPatches;
}
public static boolean loadCustomizedSetting() {
IScopeContext[] contexts = new IScopeContext[] {InstanceScope.INSTANCE, DefaultScope.INSTANCE, BundleDefaultsScope.INSTANCE, ConfigurationScope.INSTANCE};
boolean updateToLatest = Platform.getPreferencesService().getBoolean(AutomaticUpdatePlugin.PLUGIN_ID, "updateToLatest", false, contexts);
return updateToLatest;
}
}