org.eclipse.equinox.internal.p2.ui.dialogs.InstallWizard.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.equinox.internal.p2.ui.dialogs.InstallWizard.java

Source

/*******************************************************************************
 *  Copyright (c) 2007, 2010 IBM Corporation and others.
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 *     IBM Corporation - initial API and implementation
 *     Sonatype, Inc. - ongoing development
 *******************************************************************************/
package org.eclipse.equinox.internal.p2.ui.dialogs;

import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.equinox.internal.p2.ui.*;
import org.eclipse.equinox.internal.p2.ui.model.*;
import org.eclipse.equinox.p2.engine.ProvisioningContext;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.operations.InstallOperation;
import org.eclipse.equinox.p2.operations.ProfileChangeOperation;
import org.eclipse.equinox.p2.ui.LoadMetadataRepositoryJob;
import org.eclipse.equinox.p2.ui.ProvisioningUI;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * An install wizard that allows the users to browse all of the repositories
 * and search/select for items to install.
 * 
 * @since 3.6
 */
public class InstallWizard extends WizardWithLicenses {

    SelectableIUsPage errorReportingPage;
    boolean ignoreSelectionChanges = false;
    IStatus installHandlerStatus;

    public InstallWizard(ProvisioningUI ui, InstallOperation operation,
            Collection<IInstallableUnit> initialSelections, LoadMetadataRepositoryJob preloadJob) {
        super(ui, operation, initialSelections == null ? null : initialSelections.toArray(), preloadJob);
        setWindowTitle(ProvUIMessages.InstallIUOperationLabel);
        setDefaultPageImageDescriptor(ProvUIImages.getImageDescriptor(ProvUIImages.WIZARD_BANNER_INSTALL));
    }

    protected ResolutionResultsWizardPage createResolutionPage() {
        return new InstallWizardPage(ui, this, root, (InstallOperation) operation);
    }

    protected ISelectableIUsPage createMainPage(IUElementListRoot input, Object[] selections) {
        mainPage = new AvailableIUsPage(ui, this);
        if (selections != null && selections.length > 0)
            mainPage.setCheckedElements(selections);
        return mainPage;

    }

    protected void initializeResolutionModelElements(Object[] selectedElements) {
        if (selectedElements == null)
            return;
        root = new IUElementListRoot();
        ArrayList<AvailableIUElement> list = new ArrayList<AvailableIUElement>(selectedElements.length);
        ArrayList<AvailableIUElement> selections = new ArrayList<AvailableIUElement>(selectedElements.length);
        for (int i = 0; i < selectedElements.length; i++) {
            IInstallableUnit iu = ElementUtils.getIU(selectedElements[i]);
            if (iu != null) {
                AvailableIUElement element = new AvailableIUElement(root, iu, getProfileId(),
                        shouldShowProvisioningPlanChildren());
                list.add(element);
                selections.add(element);
            }
        }
        root.setChildren(list.toArray());
        planSelections = selections.toArray();
    }

    /*
     * Overridden to dynamically determine which page to get
     * selections from.  (non-Javadoc)
     * @see org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard#getOperationSelections()
     */
    protected Object[] getOperationSelections() {
        return getOperationSelectionsPage().getCheckedIUElements();
    }

    /*
     * Get the page that is driving operation selections.  This is
     * usually the main page, but it could be error page if there
     * was a resolution error and the user decides to change selections
     * and try again without going back.
     */
    protected ISelectableIUsPage getOperationSelectionsPage() {
        IWizardPage page = getContainer().getCurrentPage();
        if (page instanceof ISelectableIUsPage)
            return (ISelectableIUsPage) page;
        // return the main page if we weren't on main or error page
        return mainPage;
    }

    protected ProvisioningContext getProvisioningContext() {
        return ((AvailableIUsPage) mainPage).getProvisioningContext();
    }

    protected IResolutionErrorReportingPage createErrorReportingPage() {
        if (root == null)
            errorReportingPage = new SelectableIUsPage(ui, this, null, null);
        else
            errorReportingPage = new SelectableIUsPage(ui, this, root, root.getChildren(root));
        errorReportingPage.setTitle(ProvUIMessages.InstallWizardPage_Title);
        errorReportingPage.setDescription(ProvUIMessages.PreselectedIUInstallWizard_Description);
        errorReportingPage.updateStatus(root, operation);
        return errorReportingPage;
    }

    /* (non-Javadoc)
     * @see org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard#getProfileChangeOperation(java.lang.Object[])
     */
    protected ProfileChangeOperation getProfileChangeOperation(Object[] elements) {
        InstallOperation op = new InstallOperation(ui.getSession(), ElementUtils.elementsToIUs(elements));
        op.setProfileId(getProfileId());
        //      op.setRootMarkerKey(getRootMarkerKey());
        return op;
    }

    protected boolean shouldUpdateErrorPageModelOnPlanChange() {
        // We don't want the root of the error page to change unless we are on the
        // main page.  For example, if we are on the error page, change checkmarks, and
        // resolve again with an error, we wouldn't want the root items to change in the
        // error page.
        return getContainer().getCurrentPage() == mainPage && super.shouldUpdateErrorPageModelOnPlanChange();
    }

    protected void planChanged() {
        super.planChanged();
        synchSelections(getOperationSelectionsPage());
    }

    /*
     * overridden to ensure that the main page selections stay in synch
     * with changes to the error page.
     * (non-Javadoc)
     * @see org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard#operationSelectionsChanged(org.eclipse.equinox.internal.p2.ui.dialogs.ISelectableIUsPage)
     */
    public void operationSelectionsChanged(ISelectableIUsPage page) {
        if (ignoreSelectionChanges)
            return;
        super.operationSelectionsChanged(page);
        // If we are on the error page, resolution has failed.
        // Our ability to move on depends on whether the selections have changed.
        // If they are the same selections, then we are not complete until selections are changed.
        if (getOperationSelectionsPage() == errorPage)
            ((WizardPage) errorPage).setPageComplete(
                    pageSelectionsHaveChanged(errorPage) && errorPage.getCheckedIUElements().length > 0);
        synchSelections(page);
    }

    private void synchSelections(ISelectableIUsPage triggeringPage) {
        // We don't want our programmatic changes to cause all this to happen again
        ignoreSelectionChanges = true;
        try {
            if (triggeringPage == errorReportingPage) {
                mainPage.setCheckedElements(triggeringPage.getCheckedIUElements());
            } else if (triggeringPage == mainPage) {
                errorReportingPage.setCheckedElements(triggeringPage.getCheckedIUElements());
            }
        } finally {
            ignoreSelectionChanges = false;
        }
    }

    /*
     * Overridden to check whether there are UpdateManager install handlers in the item
     * to be installed.  Operations don't know about this compatibility issue.
     * (non-Javadoc)
     * @see org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard#getCurrentStatus()
     */
    public IStatus getCurrentStatus() {
        IStatus originalStatus = super.getCurrentStatus();
        int sev = originalStatus.getSeverity();
        // Use the previously computed status if the user cancelled or if we were already in error.
        // If we don't have an operation or a plan, we can't check this condition either, so just
        // use the normal status.
        if (sev == IStatus.CANCEL || sev == IStatus.ERROR || operation == null
                || operation.getProvisioningPlan() == null) {
            return originalStatus;
        }
        // Does the plan require install handler support?
        installHandlerStatus = UpdateManagerCompatibility.getInstallHandlerStatus(operation.getProvisioningPlan());
        if (!installHandlerStatus.isOK()) {
            // Set the status into the wizard.  This ensures future calls to this method won't
            // repeat the work (and prompting).
            couldNotResolveStatus = installHandlerStatus;

            // Is the update manager installer present?  If so, offer to open it.
            // In either case, the failure will be reported in this wizard.
            if (ProvUI.isUpdateManagerInstallerPresent()) {
                PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                    public void run() {
                        Shell shell = ProvUI.getDefaultParentShell();
                        MessageDialog dialog = new MessageDialog(shell,
                                ProvUIMessages.Policy_RequiresUpdateManagerTitle, null,
                                ProvUIMessages.Policy_RequiresUpdateManagerMessage, MessageDialog.WARNING,
                                new String[] { ProvUIMessages.LaunchUpdateManagerButton,
                                        IDialogConstants.CANCEL_LABEL },
                                0);
                        if (dialog.open() == 0)
                            BusyIndicator.showWhile(shell.getDisplay(), new Runnable() {
                                public void run() {
                                    UpdateManagerCompatibility.openInstaller();
                                }
                            });
                    }
                });
            }
            return installHandlerStatus;
        }
        return originalStatus;
    }

    /*
     * When we've found an install handler, that status trumps anything that the operation might have
     * determined.  We are relying here on the knowledge that the wizard's couldNotResolveStatus is 
     * reset on every new resolution, so that status only holds the installHandler status when it is 
     * the current status.  The installHandlerStatus must be non-OK for it to matter at all.
     * 
     * (non-Javadoc)
     * @see org.eclipse.equinox.internal.p2.ui.dialogs.ProvisioningOperationWizard#statusOverridesOperation()
     */
    public boolean statusOverridesOperation() {
        return installHandlerStatus != null && !installHandlerStatus.isOK()
                && couldNotResolveStatus == installHandlerStatus;
    }
}