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

Java tutorial

Introduction

Here is the source code for com.microsoft.alm.plugin.idea.tfvc.core.TFSCheckinEnvironment.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.intellij.ide.BrowserUtil;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.VcsNotifier;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.FunctionUtil;
import com.intellij.util.NullableFunction;
import com.intellij.util.PairConsumer;
import com.microsoft.alm.common.utils.UrlHelper;
import com.microsoft.alm.plugin.context.ServerContext;
import com.microsoft.alm.plugin.exceptions.TeamServicesException;
import com.microsoft.alm.plugin.external.utils.CommandUtils;
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.VcsHelper;
import com.microsoft.alm.plugin.idea.tfvc.core.tfs.TfsFileUtil;
import com.microsoft.alm.plugin.idea.tfvc.core.tfs.VersionControlPath;
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 java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * Handles VCS checkin features
 * TODO: comment back in the features as needed
 */
public class TFSCheckinEnvironment implements CheckinEnvironment {
    public static final Logger logger = LoggerFactory.getLogger(TFSCheckinEnvironment.class);

    private static final String CHECKIN_OPERATION_NAME = "Checkin";

    @NotNull
    private final TFSVcs myVcs;

    public TFSCheckinEnvironment(final @NotNull TFSVcs vcs) {
        myVcs = vcs;
    }

    @Nullable
    public RefreshableOnComponent createAdditionalOptionsPanel(final CheckinProjectPanel checkinProjectPanel,
            PairConsumer<Object, Object> additionalDataConsumer) {
        //        boolean isAffected = false;
        //        for (File file : checkinProjectPanel.getFiles()) {
        //            if (TFSVcs.isUnderTFS(VcsUtil.getFilePath(file), checkinProjectPanel.getProject())) {
        //                isAffected = true;
        //                break;
        //            }
        //        }
        //        if (!isAffected) {
        //            return null;
        //        }
        //
        //        final JComponent panel = new JPanel();
        //        panel.setLayout(new BorderLayout(5, 0));
        //
        //        myVcs.getCheckinData().messageLabel = new BoldLabel() {
        //
        //            @Override
        //            public JToolTip createToolTip() {
        //                JToolTip toolTip = new JToolTip() {{
        //                    setUI(new MultiLineTooltipUI());
        //                }};
        //                toolTip.setComponent(this);
        //                return toolTip;
        //            }
        //
        //        };
        //
        //        panel.add(myVcs.getCheckinData().messageLabel, BorderLayout.WEST);
        //
        //        final JButton configureButton = new JButton("Configure...");
        //        panel.add(configureButton, BorderLayout.EAST);
        //
        //        configureButton.addActionListener(new ActionListener() {
        //
        //            public void actionPerformed(final ActionEvent event) {
        //                CheckinParameters copy = myVcs.getCheckinData().parameters.createCopy();
        //
        //                CheckinParametersDialog d = new CheckinParametersDialog(checkinProjectPanel.getProject(), copy);
        //                if (d.showAndGet()) {
        //                    myVcs.getCheckinData().parameters = copy;
        //                    updateMessage(myVcs.getCheckinData());
        //                }
        //            }
        //        });
        //
        //        return new TFSAdditionalOptionsPanel(panel, checkinProjectPanel, configureButton);
        return null;
    }

    //    public static void updateMessage(TFSVcs.CheckinData checkinData) {
    //        if (checkinData.parameters == null) {
    //            return;
    //        }
    //
    //        final Pair<String, CheckinParameters.Severity> message = checkinData.parameters.getValidationMessage(CheckinParameters.Severity.BOTH);
    //        if (message == null) {
    //            checkinData.messageLabel.setText("<html>Ready to commit</html>"); // prevent bold
    //            checkinData.messageLabel.setIcon(null);
    //            checkinData.messageLabel.setToolTipText(null);
    //        } else {
    //            checkinData.messageLabel.setToolTipText(message.first);
    //            if (message.second == CheckinParameters.Severity.ERROR) {
    //                checkinData.messageLabel.setText("Errors found");
    //                checkinData.messageLabel.setIcon(UIUtil.getBalloonErrorIcon());
    //            } else {
    //                checkinData.messageLabel.setText("Warnings found");
    //                checkinData.messageLabel.setIcon(UIUtil.getBalloonWarningIcon());
    //            }
    //        }
    //    }

    @Nullable
    public String getDefaultMessageFor(final FilePath[] filesToCheckin) {
        return null;
    }

    @Nullable
    @NonNls
    public String getHelpId() {
        return null; // TODO: help id for check in
    }

    public String getCheckinOperationName() {
        return CHECKIN_OPERATION_NAME;
    }

    @Nullable
    public List<VcsException> commit(final List<Change> changes, final String preparedComment,
            @NotNull NullableFunction<Object, Object> parametersHolder, Set<String> feedback) {
        final List<VcsException> errors = new ArrayList<VcsException>();

        // set progress bar status
        final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
        TFSProgressUtil.setProgressText(progressIndicator,
                TfPluginBundle.message(TfPluginBundle.KEY_TFVC_CHECKIN_STATUS));

        // find files that are to be checked in
        final List<String> files = new ArrayList<String>();
        for (final Change change : changes) {
            String path = null;
            final ContentRevision beforeRevision = change.getBeforeRevision();
            final ContentRevision afterRevision = change.getAfterRevision();
            if (afterRevision != null) {
                path = afterRevision.getFile().getPath();
            } else if (beforeRevision != null) {
                path = beforeRevision.getFile().getPath();
            }
            if (path != null) {
                files.add(path);
            }
        }

        try {
            final ServerContext context = myVcs.getServerContext(true);
            final List<Integer> workItemIds = VcsHelper.getWorkItemIdsFromMessage(preparedComment);
            final String changesetNumber = CommandUtils.checkinFiles(context, files, preparedComment, workItemIds);

            // notify user of success
            final String changesetLink = String.format(UrlHelper.SHORT_HTTP_LINK_FORMATTER,
                    UrlHelper.getTfvcChangesetURI(context.getUri().toString(), changesetNumber),
                    TfPluginBundle.message(TfPluginBundle.KEY_TFVC_CHECKIN_LINK_TEXT, changesetNumber));
            VcsNotifier.getInstance(myVcs.getProject()).notifyImportantInfo(
                    TfPluginBundle.message(TfPluginBundle.KEY_TFVC_CHECKIN_SUCCESSFUL_TITLE),
                    TfPluginBundle.message(TfPluginBundle.KEY_TFVC_CHECKIN_SUCCESSFUL_MSG, changesetLink),
                    new NotificationListener() {
                        @Override
                        public void hyperlinkUpdate(@NotNull Notification notification,
                                @NotNull HyperlinkEvent hyperlinkEvent) {
                            BrowserUtil.browse(hyperlinkEvent.getURL());
                        }
                    });
        } catch (Exception e) {
            // no notification needs to be done by us for errors, IntelliJ handles that
            logger.warn("Error during checkin", e);
            if (e instanceof TeamServicesException) {
                // get localized message in the case of TeamServicesException otherwise the key will print out instead of the error
                errors.add(new VcsException(LocalizationServiceImpl.getInstance().getExceptionMessage(e)));
            } else {
                errors.add(new VcsException(e));
            }
        }

        return errors;
    }

    public List<VcsException> commit(List<Change> changes, String preparedComment) {
        return commit(changes, preparedComment, FunctionUtil.<Object, Object>nullConstant(), null);
    }

    @Nullable
    public List<VcsException> scheduleMissingFileForDeletion(final List<FilePath> files) {
        final List<VcsException> errors = new ArrayList<VcsException>();
        //    try {
        //      WorkstationHelper.processByWorkspaces(files, false, myVcs.getProject(), new WorkstationHelper.VoidProcessDelegate() {
        //        public void executeRequest(final WorkspaceInfo workspace, final List<ItemPath> paths) {
        //          Collection<VcsException> schedulingErrors = ScheduleForDeletion.execute(myVcs.getProject(), workspace, paths);
        //          errors.addAll(schedulingErrors);
        //        }
        //      });
        //    }
        //    catch (TfsException e) {
        //      //noinspection ThrowableInstanceNeverThrown
        //      errors.add(new VcsException(e));
        //    }
        return errors;
    }

    @Nullable
    public List<VcsException> scheduleUnversionedFilesForAddition(final List<VirtualFile> files) {
        // TODO: schedule parent folders? (Jetbrains)
        final List<VcsException> exceptions = new ArrayList<VcsException>();
        try {
            final List<String> filesToAddPaths = new ArrayList<String>(files.size());
            for (final VirtualFile file : files) {
                filesToAddPaths.add(file.getPath());
            }
            final List<String> successfullyAdded = CommandUtils.addFiles(myVcs.getServerContext(false),
                    filesToAddPaths);

            // mark files as dirty so that they refresh in local changes tab
            for (final String path : successfullyAdded) {
                final VirtualFile file = VersionControlPath.getVirtualFile(path);
                if (file != null && file.isValid()) {
                    TfsFileUtil.markFileDirty(myVcs.getProject(), file);
                }
            }

            //check all files were added
            if (successfullyAdded.size() != filesToAddPaths.size()) {
                // remove all added files from original list of files to add to give us which files weren't added
                filesToAddPaths.removeAll(successfullyAdded);
                exceptions.add(new VcsException(TfPluginBundle.message(TfPluginBundle.KEY_TFVC_ADD_ERROR,
                        StringUtils.join(filesToAddPaths, ", "))));
            }
        } catch (RuntimeException e) {
            exceptions.add(new VcsException(e));
        }
        return exceptions;
    }

    public boolean keepChangeListAfterCommit(final ChangeList changeList) {
        return false;
    }

    @Override
    public boolean isRefreshAfterCommitNeeded() {
        return true;
    }

    //    // TODO refactor this class
    //    private class TFSAdditionalOptionsPanel implements CheckinChangeListSpecificComponent {
    //        private final JComponent myPanel;
    //        private final CheckinProjectPanel myCheckinProjectPanel;
    //        private final JButton myConfigureButton;
    //        private LocalChangeList myCurrentList;
    //
    //        public TFSAdditionalOptionsPanel(JComponent panel, CheckinProjectPanel checkinProjectPanel, JButton configureButton) {
    //            myPanel = panel;
    //            myCheckinProjectPanel = checkinProjectPanel;
    //            myConfigureButton = configureButton;
    //        }
    //
    //        public JComponent getComponent() {
    //            return myPanel;
    //        }
    //
    //        public void refresh() {
    //        }
    //
    //        public void saveState() {
    //        }
    //
    //        public void restoreState() {
    //        }
    //
    //        public void onChangeListSelected(LocalChangeList list) {
    //            if (myCurrentList == list) {
    //                return;
    //            }
    //            myCurrentList = list;
    //
    //            if (!myCheckinProjectPanel.hasDiffs()) {
    //                myPanel.setVisible(false);
    //                return;
    //            }
    //
    //            myPanel.setVisible(true);
    //
    //            try {
    //                myVcs.getCheckinData().parameters = new CheckinParameters(myCheckinProjectPanel, true);
    //                myConfigureButton.setEnabled(true);
    //                updateMessage(myVcs.getCheckinData());
    //            } catch (OperationFailedException e) {
    //                myVcs.getCheckinData().parameters = null;
    //                myConfigureButton.setEnabled(false);
    //                myVcs.getCheckinData().messageLabel.setIcon(UIUtil.getBalloonErrorIcon());
    //                myVcs.getCheckinData().messageLabel.setText("Validation failed");
    //                myVcs.getCheckinData().messageLabel.setToolTipText(e.getMessage());
    //            }
    //        }
    //
    //    }
}