com.sap.dirigible.ide.jgit.command.PushCommandHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.sap.dirigible.ide.jgit.command.PushCommandHandler.java

Source

/*******************************************************************************
 * Copyright (c) 2014 SAP AG or an SAP affiliate company. All rights reserved.
 * 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.sap.dirigible.ide.jgit.command;

import java.io.File;
import java.io.IOException;
import java.net.UnknownHostException;

import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.window.Window;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.handlers.HandlerUtil;

import com.sap.dirigible.ide.common.status.StatusLineManagerUtil;
import com.sap.dirigible.ide.jgit.command.ui.PushCommandDialog;
import com.sap.dirigible.ide.jgit.connector.JGitConnector;
import com.sap.dirigible.ide.jgit.utils.CommandHandlerUtils;
import com.sap.dirigible.ide.jgit.utils.GitFileUtils;
import com.sap.dirigible.ide.jgit.utils.GitProjectProperties;
import com.sap.dirigible.ide.logging.Logger;
import com.sap.dirigible.ide.workspace.RemoteResourcesPlugin;
import com.sap.dirigible.ide.workspace.impl.DefaultProgressMonitor;
import com.sap.dirigible.ide.workspace.impl.Workspace;
import com.sap.dirigible.ide.workspace.ui.commands.AbstractWorkspaceHandler;
import com.sap.dirigible.repository.api.IRepository;

public class PushCommandHandler extends AbstractWorkspaceHandler {
    private static final String TASK_PUSHING_TO_REMOTE_REPOSITORY = Messages.PushCommandHandler_TASK_PUSHING_TO_REMOTE_REPOSITORY;
    private static final String PLEASE_MERGE_TO_MASTER_AND_THEN_CONTINUE_WORKING_ON_PROJECT = Messages.PushCommandHandler_PLEASE_MERGE_TO_MASTER_AND_THEN_CONTINUE_WORKING_ON_PROJECT;
    private static final String PUSHED_TO_REMOTE_BRANCH_S = Messages.PushCommandHandler_PUSHED_TO_REMOTE_BRANCH_S;
    private static final String PROJECT_HAS_D_CONFILCTING_FILES = Messages.PushCommandHandler_PROJECT_HAS_D_CONFILCTING_FILES;
    private static final String CONFLICTING_FILES = Messages.PushCommandHandler_CONFLICTING_FILES;
    private static final String THIS_IS_NOT_A_GIT_PROJECT = Messages.PushCommandHandler_THIS_IS_NOT_A_GIT_PROJECT;
    private static final String CHANGES_BRANCH = "changes_branch_"; //$NON-NLS-1$
    private static final String SLASH = "/"; //$NON-NLS-1$
    private static final String DOT_GIT = ".git"; //$NON-NLS-1$
    private static final String MASTER = "master"; //$NON-NLS-1$
    private static final String INCORRECT_USERNAME_AND_OR_PASSWORD_OR_GIT_REPOSITORY_URI = Messages.PushCommandHandler_INCORRECT_USERNAME_AND_OR_PASSWORD_OR_GIT_REPOSITORY_URI;
    private static final String PLEASE_CHECK_IF_PROXY_SETTINGS_ARE_SET_PROPERLY = Messages.PushCommandHandler_PLEASE_CHECK_IF_PROXY_SETTINGS_ARE_SET_PROPERLY;
    private static final String PLEASE_SELECT_ONE = Messages.PushCommandHandler_PLEASE_SELECT_ONE;

    private static final String ONLY_ONE_PROJECT_CAN_BE_PUSHED_AT_A_TIME = Messages.PushCommandHandler_ONLY_ONE_PROJECT_CAN_BE_PUSHED_AT_A_TIME;
    private static final String ERROR_DURING_PUSH = Messages.PushCommandHandler_ERROR_DURING_PUSH;
    private static final String WHILE_PUSHING_PROJECT_ERROR_OCCURED = Messages.PushCommandHandler_WHILE_PUSHING_PROJECT_ERROR_OCCURED;
    private static final String PROJECT_HAS_BEEN_PUSHED_TO_REMOTE_REPOSITORY = Messages.PushCommandHandler_PROJECT_HAS_BEEN_PUSHED_TO_REMOTE_REPOSITORY;
    private static final String NO_PROJECT_IS_SELECTED_FOR_PUSH = Messages.PushCommandHandler_NO_PROJECT_IS_SELECTED_FOR_PUSH;
    private static final Logger logger = Logger.getLogger(PushCommandHandler.class);

    public PushCommandHandler() {
        super();
    }

    @Override
    public Object execute(ExecutionEvent event) throws ExecutionException {
        final ISelection selection = HandlerUtil.getActiveMenuSelection(event);
        if (selection.isEmpty()) {
            logger.warn(NO_PROJECT_IS_SELECTED_FOR_PUSH);
            StatusLineManagerUtil.setWarningMessage(NO_PROJECT_IS_SELECTED_FOR_PUSH);
            MessageDialog.openWarning(null, NO_PROJECT_IS_SELECTED_FOR_PUSH, PLEASE_SELECT_ONE);
            return null;
        }
        final IProject[] projects = CommandHandlerUtils.getProjects(selection, logger);
        if (projects.length == 0) {
            logger.warn(NO_PROJECT_IS_SELECTED_FOR_PUSH);
            StatusLineManagerUtil.setWarningMessage(NO_PROJECT_IS_SELECTED_FOR_PUSH);
            MessageDialog.openWarning(null, NO_PROJECT_IS_SELECTED_FOR_PUSH, PLEASE_SELECT_ONE);
            return null;
        } else if (projects.length > 1) {
            logger.warn(ONLY_ONE_PROJECT_CAN_BE_PUSHED_AT_A_TIME);
            StatusLineManagerUtil.setWarningMessage(ONLY_ONE_PROJECT_CAN_BE_PUSHED_AT_A_TIME);
            MessageDialog.openWarning(null, ONLY_ONE_PROJECT_CAN_BE_PUSHED_AT_A_TIME, PLEASE_SELECT_ONE);
            return null;
        }

        final IProject selectedProject = projects[0];

        DefaultProgressMonitor monitor = new DefaultProgressMonitor();
        monitor.beginTask(TASK_PUSHING_TO_REMOTE_REPOSITORY, IProgressMonitor.UNKNOWN);

        final Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
        PushCommandDialog pushCommandDialog = new PushCommandDialog(parent);
        switch (pushCommandDialog.open()) {
        case Window.OK:
            final String commitMessage = pushCommandDialog.getCommitMessage();
            final String username = pushCommandDialog.getUsername();
            final String password = pushCommandDialog.getPassword();
            final String email = pushCommandDialog.getEmail();
            pushProjectToGitRepository(selectedProject, commitMessage, username, email, password);
            break;
        }

        monitor.done();
        return null;
    }

    private void pushProjectToGitRepository(final IProject selectedProject, final String commitMessage,
            final String username, final String email, final String password) {

        final String errorMessage = String.format(WHILE_PUSHING_PROJECT_ERROR_OCCURED, selectedProject.getName());
        GitProjectProperties gitProperties = null;
        try {
            gitProperties = GitFileUtils.getGitPropertiesForProject(selectedProject,
                    RemoteResourcesPlugin.getUserName());
        } catch (IOException e) {
            MessageDialog.openError(null, THIS_IS_NOT_A_GIT_PROJECT, errorMessage);
            return;
        }
        File tempGitDirectory = null;
        try {
            String gitRepositoryURI = gitProperties.getURL();
            String repositoryName = gitRepositoryURI.substring(gitRepositoryURI.lastIndexOf(SLASH) + 1,
                    gitRepositoryURI.lastIndexOf(DOT_GIT));
            tempGitDirectory = GitFileUtils
                    .createTempDirectory(JGitConnector.TEMP_DIRECTORY_PREFIX + repositoryName);
            JGitConnector.cloneRepository(tempGitDirectory, gitRepositoryURI, username, password);

            Repository repository = JGitConnector.getRepository(tempGitDirectory.toString());
            JGitConnector jgit = new JGitConnector(repository);
            String lastSHA = gitProperties.getSHA();

            final String changesBranch = CHANGES_BRANCH + RemoteResourcesPlugin.getUserName();
            jgit.checkout(lastSHA);
            jgit.createBranch(changesBranch, lastSHA);
            jgit.checkout(changesBranch);

            GitFileUtils.deleteProjectFolderFromDirectory(tempGitDirectory, selectedProject.getName());
            GitFileUtils.copyProjectToDirectory(selectedProject, tempGitDirectory);

            jgit.add(selectedProject.getName());
            jgit.commit(commitMessage, username, email, true);
            jgit.pull();
            int numberOfConflictingFiles = jgit.status().getConflicting().size();
            if (numberOfConflictingFiles == 0) {
                jgit.checkout(MASTER);
                jgit.rebase(changesBranch);
                jgit.push(username, password);

                String dirigibleUser = RemoteResourcesPlugin.getUserName();

                GitFileUtils.deleteDGBRepositoryProject(selectedProject, dirigibleUser);

                Workspace workspace = (Workspace) RemoteResourcesPlugin.getWorkspace();
                IRepository dirigibleRepository = workspace.getRepository();

                String workspacePath = String.format(GitProjectProperties.DB_DIRIGIBLE_USERS_S_WORKSPACE,
                        dirigibleUser);

                String newLastSHA = jgit.getLastSHAForBranch(MASTER);
                gitProperties.setSHA(newLastSHA);

                GitFileUtils.importProject(tempGitDirectory, dirigibleRepository, workspacePath, dirigibleUser,
                        gitProperties);

                refreshWorkspace();
                StatusLineManagerUtil.setInfoMessage(
                        String.format(PROJECT_HAS_BEEN_PUSHED_TO_REMOTE_REPOSITORY, selectedProject.getName()));
            } else {
                jgit.hardReset();
                jgit.push(username, password);
                String statusLineMessage = String.format(PROJECT_HAS_D_CONFILCTING_FILES, numberOfConflictingFiles);
                StatusLineManagerUtil.setWarningMessage(statusLineMessage);
                String message = String.format(
                        PROJECT_HAS_D_CONFILCTING_FILES + PUSHED_TO_REMOTE_BRANCH_S
                                + PLEASE_MERGE_TO_MASTER_AND_THEN_CONTINUE_WORKING_ON_PROJECT,
                        numberOfConflictingFiles, changesBranch);
                MessageDialog.openWarning(null, CONFLICTING_FILES, message);
            }
        } catch (IOException e) {
            logger.error(errorMessage, e);
            MessageDialog.openError(null, ERROR_DURING_PUSH, errorMessage);
        } catch (CoreException e) {
            logger.error(errorMessage, e);
            MessageDialog.openError(null, ERROR_DURING_PUSH, errorMessage);
        } catch (InvalidRemoteException e) {
            logger.error(errorMessage, e);
            MessageDialog.openError(null, ERROR_DURING_PUSH, errorMessage + "\n" + e.getMessage()); //$NON-NLS-1$
        } catch (TransportException e) {
            logger.error(errorMessage, e);
            Throwable rootCause = e.getCause();
            if (rootCause != null) {
                rootCause = rootCause.getCause();
                if (rootCause instanceof UnknownHostException) {
                    MessageDialog.openError(null, errorMessage, PLEASE_CHECK_IF_PROXY_SETTINGS_ARE_SET_PROPERLY);
                } else {
                    MessageDialog.openError(null, errorMessage,
                            e.getCause().getMessage() + INCORRECT_USERNAME_AND_OR_PASSWORD_OR_GIT_REPOSITORY_URI);
                }
            }
        } catch (GitAPIException e) {
            logger.error(errorMessage, e);
            MessageDialog.openError(null, ERROR_DURING_PUSH, errorMessage);
        } finally {
            GitFileUtils.deleteDirectory(tempGitDirectory);
        }
    }
}