com.microsoft.alm.plugin.idea.tfvc.core.TFSVcs.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.alm.plugin.idea.tfvc.core.TFSVcs.java

Source

// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See License.txt in the project root.

package com.microsoft.alm.plugin.idea.tfvc.core;

import com.google.common.util.concurrent.SettableFuture;
import com.intellij.ide.BrowserUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.progress.PerformInBackgroundOption;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.CheckoutProvider;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.VcsShowConfirmationOption;
import com.intellij.openapi.vcs.VcsShowSettingOption;
import com.intellij.openapi.vcs.changes.ChangeProvider;
import com.intellij.openapi.vcs.diff.DiffProvider;
import com.intellij.openapi.vcs.history.VcsHistoryProvider;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import com.intellij.vcsUtil.VcsUtil;
import com.microsoft.alm.plugin.context.RepositoryContext;
import com.microsoft.alm.plugin.context.ServerContext;
import com.microsoft.alm.plugin.context.ServerContextManager;
import com.microsoft.alm.plugin.external.exceptions.SyncException;
import com.microsoft.alm.plugin.external.exceptions.ToolException;
import com.microsoft.alm.plugin.external.tools.TfTool;
import com.microsoft.alm.plugin.idea.common.resources.TfPluginBundle;
import com.microsoft.alm.plugin.idea.common.services.LocalizationServiceImpl;
import com.microsoft.alm.plugin.idea.common.utils.IdeaHelper;
import com.microsoft.alm.plugin.idea.common.utils.VcsHelper;
import com.microsoft.alm.plugin.idea.tfvc.core.tfs.TfsRevisionNumber;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.event.HyperlinkEvent;
import javax.ws.rs.NotAuthorizedException;

/**
 * Class that sets up the TFS version control extension.
 * <p/>
 * TODO: comment back in code as more features are added
 */
public class TFSVcs extends AbstractVcs {
    public static final Logger logger = LoggerFactory.getLogger(TFSVcs.class);
    private static boolean hasVersionBeenVerified = false;

    @NonNls
    public static final String TFVC_NAME = "TFVC";
    public static final String TFVC_ONLINE_HELP_URL = "http://java.visualstudio.com/Docs/tools/intelliJ#_tfvc-support-preview";
    public static final String HELP_URL_EVENT = "url";
    public static final String SETTINGS_URL_EVENT = "settings";
    private static final VcsKey ourKey = createKey(TFVC_NAME);

    //  TODO: private VcsVFSListener myFileListener;
    private final VcsShowConfirmationOption myAddConfirmation;
    private final VcsShowConfirmationOption myDeleteConfirmation;
    private final VcsShowSettingOption myCheckoutOptions;

    private VcsHistoryProvider myHistoryProvider;
    private DiffProvider myDiffProvider;
    private TFSCheckinEnvironment myCheckinEnvironment;
    private UpdateEnvironment myUpdateEnvironment;

    public TFSVcs(@NotNull Project project) {
        super(project, TFVC_NAME);
        final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project);
        myAddConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, this);
        myDeleteConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.REMOVE,
                this);
        myCheckoutOptions = vcsManager.getStandardOption(VcsConfiguration.StandardOption.CHECKOUT, this);
    }

    public static TFSVcs getInstance(Project project) {
        return (TFSVcs) ProjectLevelVcsManager.getInstance(project).findVcsByName(TFVC_NAME);
    }

    @NonNls
    public String getDisplayName() {
        return TFVC_NAME;
    }

    public Configurable getConfigurable() {
        return new TFSProjectConfigurable(myProject);
    }

    @Override
    public void activate() {
        //    TODO: myFileListener = new TFSFileListener(getProject(), this);
        //    TODO: TfsSdkManager.activate();
        checkCommandLineVersion();
    }

    @Override
    public void deactivate() {
        //    TODO: Disposer.dispose(myFileListener);
    }

    public VcsShowConfirmationOption getAddConfirmation() {
        return myAddConfirmation;
    }

    public VcsShowConfirmationOption getDeleteConfirmation() {
        return myDeleteConfirmation;
    }

    public VcsShowSettingOption getCheckoutOptions() {
        return myCheckoutOptions;
    }

    public ChangeProvider getChangeProvider() {
        return new TFSChangeProvider(myProject);
    }

    @NotNull
    public TFSCheckinEnvironment createCheckinEnvironment() {
        if (myCheckinEnvironment == null) {
            myCheckinEnvironment = new TFSCheckinEnvironment(this);
        }
        return myCheckinEnvironment;
    }

    @NotNull
    public UpdateEnvironment createUpdateEnvironment() {
        if (myUpdateEnvironment == null) {
            myUpdateEnvironment = new TFSUpdateEnvironment(this);
        }
        return myUpdateEnvironment;
    }

    public RollbackEnvironment createRollbackEnvironment() {
        return new TFSRollbackEnvironment(this, myProject);
    }

    public boolean fileIsUnderVcs(final FilePath filePath) {
        return isVersionedDirectory(filePath.getVirtualFile());
    }

    /*
    TODO:
    public boolean isVersionedDirectory(final VirtualFile dir) {
    if (dir == null) {
        return false;
    }
    return (!Workstation.getInstance().findWorkspacesCached(TfsFileUtil.getFilePath(dir), false).isEmpty());
    }
        
        
    public EditFileProvider getEditFileProvider() {
    return new TFSEditFileProvider(myProject);
    }
        
    @NotNull
    public CommittedChangesProvider<TFSChangeList, ChangeBrowserSettings> getCommittedChangesProvider() {
    if (myCommittedChangesProvider == null) {
        myCommittedChangesProvider = new TFSCommittedChangesProvider(myProject);
    }
    return null; //myCommittedChangesProvider;
    }
    */

    @Override
    public VcsHistoryProvider getVcsHistoryProvider() {
        if (myHistoryProvider == null) {
            myHistoryProvider = new TFSHistoryProvider(myProject);
        }
        return myHistoryProvider;
    }

    @Override
    public DiffProvider getDiffProvider() {
        if (myDiffProvider == null) {
            myDiffProvider = new TFSDiffProvider(myProject);
        }
        return myDiffProvider;
    }

    @Nullable
    public VcsRevisionNumber parseRevisionNumber(final String revisionNumberString) {
        return TfsRevisionNumber.tryParse(revisionNumberString);
    }

    @Nullable
    public String getRevisionPattern() {
        return ourIntegerPattern;
    }

    public static VcsKey getKey() {
        return ourKey;
    }

    public static boolean isUnderTFS(FilePath path, Project project) {
        AbstractVcs vcs = VcsUtil.getVcsFor(project, path);
        return vcs != null && TFVC_NAME.equals(vcs.getName());
    }

    public static VcsException convertToVcsException(final Throwable throwable) {
        if (throwable instanceof VcsException) {
            return (VcsException) throwable;
        }

        final VcsException exception = new VcsException(throwable.getMessage(), throwable);
        if (throwable instanceof SyncException) {
            exception.setIsWarning(((SyncException) throwable).isWarning());
        }

        return exception;
    }

    @Override
    public CheckoutProvider getCheckoutProvider() {
        return null; ///TODO: new TFSCheckoutProvider();
    }

    /**
     * This method is used by the environment classes to get the ServerContext.
     * We do not cache it here because it should already be cached in the ServerContextManager.
     */
    public ServerContext getServerContext(boolean throwIfNotFound) {
        final RepositoryContext repositoryContext = VcsHelper.getRepositoryContext(getProject());
        logger.info("TFSVcs.getServerContext repositoryContext is null: " + (repositoryContext == null));

        final ServerContext serverContext = repositoryContext != null
                ? ServerContextManager.getInstance().createContextFromTfvcServerUrl(repositoryContext.getUrl(),
                        repositoryContext.getTeamProjectName(), true)
                : null;

        if (serverContext == null && throwIfNotFound) {
            // TODO: throw a better error b/c this is what the user sees and it's confusing
            throw new NotAuthorizedException(repositoryContext != null ? repositoryContext.getUrl() : "");
        }
        return serverContext;
    }

    private void checkCommandLineVersion() {
        if (hasVersionBeenVerified) {
            // No need to check the version again if we have already checked it once this session
            logger.info("Skipping the attempt to check the version of the TF command line.");
            return;
        }

        hasVersionBeenVerified = true;

        // We want to start a background thread to check the version, but that can only be done
        // form the UI thread.
        IdeaHelper.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                final SettableFuture<String> versionMessage = SettableFuture.create();
                (new Task.Backgroundable(getProject(),
                        TfPluginBundle.message(TfPluginBundle.KEY_TFVC_TF_VERSION_WARNING_PROGRESS), false,
                        PerformInBackgroundOption.ALWAYS_BACKGROUND) {
                    public void run(@NotNull final ProgressIndicator indicator) {
                        try {
                            logger.info("Attempting to check the version of the TF command line.");
                            TfTool.checkVersion();
                            versionMessage.set(StringUtils.EMPTY);
                        } catch (final ToolException ex) {
                            final String error = LocalizationServiceImpl.getInstance().getExceptionMessage(ex);
                            logger.warn(error);
                            versionMessage.set(error);
                        } catch (final Throwable t) {
                            // Don't let unknown errors bubble out here
                            logger.warn("Unexpected error when checking the version of the command line.", t);
                        }
                    }

                    public void onSuccess() {
                        try {
                            final String error = versionMessage.get();
                            if (StringUtils.isNotEmpty(error)) {
                                logger.info("Notifying the user of the min version problem.");
                                // Notify the user that they should upgrade their version of the TF command line
                                VcsNotifier.getInstance(getProject()).notifyImportantWarning(
                                        TfPluginBundle.message(TfPluginBundle.KEY_TFVC_TF_VERSION_WARNING_TITLE),
                                        error, new NotificationListener.Adapter() {

                                            @Override
                                            protected void hyperlinkActivated(@NotNull Notification notification,
                                                    @NotNull HyperlinkEvent hyperlinkEvent) {
                                                if (SETTINGS_URL_EVENT.equals(hyperlinkEvent.getDescription())) {
                                                    ShowSettingsUtil.getInstance().showSettingsDialog(myProject,
                                                            getConfigurable().getDisplayName());
                                                } else if (HELP_URL_EVENT.equals(hyperlinkEvent.getDescription())) {
                                                    BrowserUtil.browse(TFVC_ONLINE_HELP_URL);
                                                } else {
                                                    logger.warn("Unknown hyperlinkEvent triggered: "
                                                            + hyperlinkEvent.getDescription());
                                                }
                                            }
                                        });
                            }
                        } catch (Exception e) {
                            logger.warn("Failed to warn user about min version of TF command line.", e);
                        }
                    }
                }).queue();
            }
        });
    }
}