Package org.eclipse.egit.ui.internal.push

Source Code of org.eclipse.egit.ui.internal.push.PushWizard$PushJob

/*******************************************************************************
* Copyright (C) 2008, Marek Zawirski <marek.zawirski@gmail.com>
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
* Copyright (C) 2012, Robin Stocker <robin@nibor.org>
*
* 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
*******************************************************************************/
package org.eclipse.egit.ui.internal.push;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.egit.core.op.PushOperation;
import org.eclipse.egit.core.op.PushOperationResult;
import org.eclipse.egit.core.op.PushOperationSpecification;
import org.eclipse.egit.core.securestorage.UserPasswordCredentials;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.UIPreferences;
import org.eclipse.egit.ui.internal.SecureStoreUtils;
import org.eclipse.egit.ui.internal.UIIcons;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.egit.ui.internal.components.RefSpecPage;
import org.eclipse.egit.ui.internal.components.RepositorySelection;
import org.eclipse.egit.ui.internal.components.RepositorySelectionPage;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.RefSpec;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.RemoteRefUpdate;
import org.eclipse.jgit.transport.Transport;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
* Wizard allowing user to specify all needed data to push to another repository
* - including selection of remote repository and refs specifications.
* <p>
* Push operation is performed upon successful completion of this wizard.
*/
public class PushWizard extends Wizard {
  private static final String HELP_CONTEXT = "org.eclipse.egit.ui.PushWizard"; //$NON-NLS-1$

  private static String getURIsString(final Collection<URIish> uris) {
    final StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (final URIish uri : uris) {
      if (first)
        first = false;
      else
        sb.append(", "); //$NON-NLS-1$
      sb.append(uri);
    }
    return sb.toString();
  }

  private Repository localDb;

  private final RepositorySelectionPage repoPage;

  private final RefSpecPage refSpecPage;

  private ConfirmationPage confirmPage;

  /**
   * Create push wizard for specified local repository.
   *
   * @param localDb
   *            repository to push from.
   * @throws URISyntaxException
   *             when configuration of this repository contains illegal URIs.
   */
  public PushWizard(final Repository localDb) throws URISyntaxException {
    this.localDb = localDb;
    final List<RemoteConfig> remotes = RemoteConfig
        .getAllRemoteConfigs(localDb.getConfig());
    repoPage = new RepositorySelectionPage(false, remotes, null);
    repoPage.setHelpContext(HELP_CONTEXT);
    refSpecPage = new RefSpecPage(localDb, true) {
      @Override
      public void setVisible(boolean visible) {
        if (visible) {
          setSelection(repoPage.getSelection());
          setCredentials(repoPage.getCredentials());
        }
        super.setVisible(visible);
      }
    };
    refSpecPage.setHelpContext(HELP_CONTEXT);
    confirmPage = new ConfirmationPage(localDb) {
      @Override
      public void setVisible(boolean visible) {
        if (visible) {
          setSelection(repoPage.getSelection(), refSpecPage
              .getRefSpecs());
          setCredentials(repoPage.getCredentials());
        }
        super.setVisible(visible);
      }
    };
    confirmPage.setHelpContext(HELP_CONTEXT);
    setDefaultPageImageDescriptor(UIIcons.WIZBAN_PUSH);
    setNeedsProgressMonitor(true);
  }

  @Override
  public void addPages() {
    addPage(repoPage);
    addPage(refSpecPage);
    addPage(confirmPage);
  }

  @Override
  public boolean canFinish() {
    if (getContainer().getCurrentPage() == repoPage) {
      RepositorySelection sel = repoPage.getSelection();
      if (sel.isConfigSelected()) {
        RemoteConfig config = sel.getConfig();
        return !config.getPushURIs().isEmpty()
            || !config.getURIs().isEmpty();
      }
    }
    return super.canFinish();
  }

  @Override
  public boolean performFinish() {
    boolean calledFromRepoPage = false;
    if (getContainer().getCurrentPage()==repoPage)
      calledFromRepoPage = true;
    if (repoPage.getSelection().isConfigSelected()
        && refSpecPage.isSaveRequested()) {
      saveRefSpecs();
    }

    if (repoPage.getStoreInSecureStore()) {
      if (!SecureStoreUtils.storeCredentials(repoPage
          .getCredentials(), repoPage.getSelection().getURI()))
        return false;
    }

    final PushOperation operation = createPushOperation(calledFromRepoPage);
    if (operation == null)
      return false;
    UserPasswordCredentials credentials = repoPage.getCredentials();
    if (credentials != null)
      operation.setCredentialsProvider(new UsernamePasswordCredentialsProvider(
          credentials.getUser(), credentials.getPassword()));
    final PushOperationResult resultToCompare;
    if (confirmPage.isShowOnlyIfChangedSelected())
      resultToCompare = confirmPage.getConfirmedResult();
    else
      resultToCompare = null;
    final Job job = new PushJob(localDb, operation, resultToCompare,
        getDestinationString(repoPage.getSelection()));

    job.setUser(true);
    job.schedule();
    repoPage.saveUriInPrefs();

    return true;
  }

  @Override
  public String getWindowTitle() {
    final IWizardPage currentPage = getContainer().getCurrentPage();
    if (currentPage == repoPage || currentPage == null)
      return UIText.PushWizard_windowTitleDefault;
    final String destination = getDestinationString(repoPage.getSelection());
    return NLS.bind(UIText.PushWizard_windowTitleWithDestination,
        destination);
  }

  private void saveRefSpecs() {
    final RemoteConfig rc = repoPage.getSelection().getConfig();
    rc.setPushRefSpecs(refSpecPage.getRefSpecs());
    final StoredConfig config = localDb.getConfig();
    rc.update(config);
    try {
      config.save();
    } catch (final IOException e) {
      ErrorDialog.openError(getShell(), UIText.PushWizard_cantSaveTitle,
          UIText.PushWizard_cantSaveMessage, new Status(
              IStatus.WARNING, Activator.getPluginId(), e
                  .getMessage(), e));
      // Continue, it's not critical.
    }
  }

  private PushOperation createPushOperation(boolean calledFromRepoPage) {
    try {
      final PushOperationSpecification spec;
      final RemoteConfig config = repoPage.getSelection().getConfig();
      if (calledFromRepoPage) {
        // obtain the push ref specs from the configuration
        // use our own list here, as the config returns a non-modifiable
        // list
        final Collection<RefSpec> pushSpecs = new ArrayList<RefSpec>();
        pushSpecs.addAll(config.getPushRefSpecs());
        final Collection<RemoteRefUpdate> updates = Transport
            .findRemoteRefUpdatesFor(localDb, pushSpecs,
                config.getFetchRefSpecs());
        spec = new PushOperationSpecification();
        for (final URIish uri : repoPage.getSelection().getPushURIs())
          spec.addURIRefUpdates(uri, ConfirmationPage
              .copyUpdates(updates));
      } else if (confirmPage.isConfirmed()) {
        final PushOperationResult confirmedResult = confirmPage
            .getConfirmedResult();
        spec = confirmedResult.deriveSpecification(confirmPage
            .isRequireUnchangedSelected());
      } else {
        final Collection<RefSpec> fetchSpecs;
        if (config != null)
          fetchSpecs = config.getFetchRefSpecs();
        else
          fetchSpecs = null;

        final Collection<RemoteRefUpdate> updates = Transport
            .findRemoteRefUpdatesFor(localDb, refSpecPage
                .getRefSpecs(), fetchSpecs);
        if (updates.isEmpty()) {
          ErrorDialog.openError(getShell(),
              UIText.PushWizard_missingRefsTitle, null,
              new Status(IStatus.ERROR, Activator.getPluginId(),
                  UIText.PushWizard_missingRefsMessage));
          return null;
        }

        spec = new PushOperationSpecification();
        for (final URIish uri : repoPage.getSelection().getPushURIs())
          spec.addURIRefUpdates(uri, ConfirmationPage
              .copyUpdates(updates));
      }
      int timeout = Activator.getDefault().getPreferenceStore().getInt(
          UIPreferences.REMOTE_CONNECTION_TIMEOUT);
      return new PushOperation(localDb, spec, false, timeout);
    } catch (final IOException e) {
      ErrorDialog.openError(getShell(),
          UIText.PushWizard_cantPrepareUpdatesTitle,
          UIText.PushWizard_cantPrepareUpdatesMessage, new Status(
              IStatus.ERROR, Activator.getPluginId(), e
                  .getMessage(), e));
      return null;
    }
  }

  static String getDestinationString(RepositorySelection repoSelection) {
    final String destination;
    if (repoSelection.isConfigSelected())
      destination = repoSelection.getConfigName();
    else
      destination = repoSelection.getURI(true).toString();
    return destination;
  }

  static class PushJob extends Job {
    private final PushOperation operation;

    private final PushOperationResult resultToCompare;

    private final String destinationString;

    private Repository localDb;

    public PushJob(final Repository localDb, final PushOperation operation,
        final PushOperationResult resultToCompare,
        final String destinationString) {
      super(NLS.bind(UIText.PushWizard_jobName, getURIsString(operation
          .getSpecification().getURIs())));
      this.operation = operation;
      this.resultToCompare = resultToCompare;
      this.destinationString = destinationString;
      this.localDb = localDb;
    }

    @Override
    protected IStatus run(final IProgressMonitor monitor) {
      try {
        operation.run(monitor);
      } catch (final InvocationTargetException e) {
        return new Status(IStatus.ERROR, Activator.getPluginId(),
            UIText.PushWizard_unexpectedError, e.getCause());
      }

      final PushOperationResult result = operation.getOperationResult();
      if (!result.isSuccessfulConnectionForAnyURI()) {
        return new Status(IStatus.ERROR, Activator.getPluginId(), NLS
            .bind(UIText.PushWizard_cantConnectToAny, result
                .getErrorStringForAllURis()));
      }

      if (resultToCompare == null || !result.equals(resultToCompare)) {
        PlatformUI.getWorkbench().getDisplay().asyncExec(
            new Runnable() {
              public void run() {
                final Shell shell = PlatformUI.getWorkbench()
                    .getActiveWorkbenchWindow().getShell();
                final Dialog dialog = new PushResultDialog(
                    shell, localDb, result,
                    destinationString);
                dialog.open();
              }
            });
      }
      return Status.OK_STATUS;
    }
  }
}
TOP

Related Classes of org.eclipse.egit.ui.internal.push.PushWizard$PushJob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.