/******************************************************************************* * Copyright (c) 2011, 2015 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, 427195 *******************************************************************************/ 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 Set<IInstallableUnit> selectedUnitsToMigrate; // selected units to be migrated, initially contains all units not installed in current profile. 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); updateTableSorting(i); } else { column.getColumn().setWidth(200); } 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[] {4, 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); } } }); selectedUnitsToMigrate = identifyUnitsToBeMigrated(); 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.item instanceof TreeItem && event.detail == SWT.CHECK) { TreeItem treeItem = (TreeItem) event.item; IInstallableUnit iu = ProvUI.getAdapter(event.item.getData(), IInstallableUnit.class); if (treeItem.getChecked()) { selectedUnitsToMigrate.add(iu); } else { selectedUnitsToMigrate.remove(iu); } } 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()) { if (item.getChecked()) { item.setChecked(false); 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); } viewer.setSubtreeChecked(item.getData(), false); } updatePageCompletion(); } }); } private Set<IInstallableUnit> identifyUnitsToBeMigrated() { Set<IInstallableUnit> ius = new HashSet<IInstallableUnit>(); if (profile != null) { for (IInstallableUnit iu : unitsToMigrate) { IQueryResult<IInstallableUnit> collector = profile.query(QueryUtil.createIUQuery(iu.getId(), new VersionRange(iu.getVersion(), true, null, false)), new NullProgressMonitor()); if (collector.isEmpty()) { ius.add(iu); } } } return ius; } 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) { IInstallableUnit iu = ProvUI.getAdapter(element, IInstallableUnit.class); if (selectedUnitsToMigrate.contains(iu)) { return true; } return false; } }; } 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) { 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(ui); 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.parseBoolean(currentIU.getProperty(IInstallableUnit.PROP_PARTIAL_IU)) && !Boolean.parseBoolean(iu.getProperty(IInstallableUnit.PROP_PARTIAL_IU))) 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; } }