| /******************************************************************************* |
| * 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; |
| } |
| |
| } |