Package com.urswolfer.intellij.plugin.gerrit.extension

Source Code of com.urswolfer.intellij.plugin.gerrit.extension.GerritCheckoutProvider$Proxy

/*
* Copyright 2000-2011 JetBrains s.r.o.
* Copyright 2013 Urs Wolfer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.urswolfer.intellij.plugin.gerrit.extension;

import com.google.common.io.ByteStreams;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.common.ProjectInfo;
import com.google.gerrit.extensions.restapi.Url;
import com.google.inject.Inject;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.CheckoutProvider;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.urswolfer.intellij.plugin.gerrit.GerritModule;
import com.urswolfer.intellij.plugin.gerrit.GerritSettings;
import com.urswolfer.intellij.plugin.gerrit.rest.GerritUtil;
import com.urswolfer.intellij.plugin.gerrit.util.NotificationBuilder;
import com.urswolfer.intellij.plugin.gerrit.util.NotificationService;
import git4idea.actions.BasicAction;
import git4idea.checkout.GitCheckoutProvider;
import git4idea.checkout.GitCloneDialog;
import git4idea.commands.Git;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
* Parts based on org.jetbrains.plugins.github.GithubCheckoutProvider
*
* @author oleg
* @author Urs Wolfer
*/
public class GerritCheckoutProvider implements CheckoutProvider {

    @Inject
    private LocalFileSystem localFileSystem;
    @Inject
    private GerritUtil gerritUtil;
    @Inject
    private GerritSettings gerritSettings;
    @Inject
    private Logger log;
    @Inject
    private NotificationService notificationService;
    @Inject
    private GerritApi gerritApi;

    @Override
    public void doCheckout(@NotNull final Project project, @Nullable final Listener listener) {
        if (!gerritUtil.testGitExecutable(project)) {
            return;
        }
        BasicAction.saveAll();
        List<ProjectInfo> availableProjects = null;
        try {
            availableProjects = gerritUtil.getAvailableProjects(project);
        } catch (Exception e) {
            log.info(e);
            NotificationBuilder notification = new NotificationBuilder(
                    project,
                    "Couldn't get the list of Gerrit repositories",
                    gerritUtil.getErrorTextFromException(e));
            notificationService.notifyError(notification);
        }
        if (availableProjects == null) {
            return;
        }
        Collections.sort(availableProjects, new Comparator<ProjectInfo>() {
            @Override
            public int compare(final ProjectInfo p1, final ProjectInfo p2) {
                return p1.id.compareTo(p2.id);
            }
        });

        final GitCloneDialog dialog = new GitCloneDialog(project);
        // Add predefined repositories to history
        for (int i = availableProjects.size() - 1; i >= 0; i--) {
            dialog.prependToHistory(gerritSettings.getHost() + '/' + Url.decode(availableProjects.get(i).id));
        }
        dialog.show();
        if (!dialog.isOK()) {
            return;
        }
        dialog.rememberSettings();
        final VirtualFile destinationParent = localFileSystem.findFileByIoFile(new File(dialog.getParentDirectory()));
        if (destinationParent == null) {
            return;
        }
        final String sourceRepositoryURL = dialog.getSourceRepositoryURL();
        final String directoryName = dialog.getDirectoryName();
        final String parentDirectory = dialog.getParentDirectory();

        Git git = ServiceManager.getService(Git.class);

        Listener listenerWrapper = addCommitMsgHookListener(listener, directoryName, parentDirectory, project);

        GitCheckoutProvider.clone(project, git, listenerWrapper, destinationParent, sourceRepositoryURL, directoryName, parentDirectory);
    }

    @Override
    public String getVcsName() {
        return "Gerrit";
    }

    /*
     * Since this is a listener which needs to be executed in any case, it cannot be a normal checkout-listener.
     * Checkout-listeners only get executed when "previous" listener got not executed (returns false).
     * Example: If user decides to setup a new project from newly created checkout, our listener does not get executed.
     */
    private Listener addCommitMsgHookListener(final Listener listener, final String directoryName, final String parentDirectory, final Project project) {
        return new Listener() {
            @Override
            public void directoryCheckedOut(File directory, VcsKey vcs) {
                setupCommitMsgHook(parentDirectory, directoryName, project);

                if (listener != null) listener.directoryCheckedOut(directory, vcs);
            }

            @Override
            public void checkoutCompleted() {
                if (listener != null) listener.checkoutCompleted();
            }
        };
    }

    private void setupCommitMsgHook(String parentDirectory, String directoryName, Project project) {
        try {
            InputStream commitMessageHook = gerritApi.tools().getCommitMessageHook();
            File targetFile = new File(parentDirectory + '/' + directoryName + "/.git/hooks/commit-msg");
            ByteStreams.copy(commitMessageHook, new FileOutputStream(targetFile));
            //noinspection ResultOfMethodCallIgnored
            targetFile.setExecutable(true);
        } catch (Exception e) {
            log.info(e);
            NotificationBuilder notification = new NotificationBuilder(
                    project,
                    "Couldn't set up Gerrit Commit-Message Hook. Please do it manually.",
                    gerritUtil.getErrorTextFromException(e));
            notificationService.notifyError(notification);
        }
    }

    public static final class Proxy implements CheckoutProvider {
        private final CheckoutProvider delegate;

        public Proxy() {
            delegate = GerritModule.getInstance(GerritCheckoutProvider.class);
        }

        @Override
        public void doCheckout(@NotNull Project project, @Nullable Listener listener) {
            delegate.doCheckout(project, listener);
        }

        @Override
        @NonNls
        public String getVcsName() {
            return delegate.getVcsName();
        }
    }
}
TOP

Related Classes of com.urswolfer.intellij.plugin.gerrit.extension.GerritCheckoutProvider$Proxy

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.