org.zend.sdkcli.internal.commands.GitCloneProjectCommand.java Source code

Java tutorial

Introduction

Here is the source code for org.zend.sdkcli.internal.commands.GitCloneProjectCommand.java

Source

/*******************************************************************************
 * Copyright (c) Sep 6, 2011 Zend Technologies Ltd. 
 * 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.zend.sdkcli.internal.commands;

import java.io.File;
import java.io.PrintWriter;
import java.net.URISyntaxException;
import java.text.MessageFormat;

import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.URIish;
import org.zend.sdkcli.GitHelper;
import org.zend.sdkcli.internal.mapping.CliMappingLoader;
import org.zend.sdkcli.internal.options.Option;
import org.zend.sdklib.application.ZendProject;

/**
 * Clones repository based on provided remote repository URL.
 * 
 * @author Wojciech Galanciak, 2011
 * 
 */
public class GitCloneProjectCommand extends AbstractGitCommand {

    private static final String GITHUB_HOST = "github.com";
    private static final String REPO = "r";
    private static final String DIR = "d";
    private static final String BRANCH = "b";

    @Option(opt = REPO, required = true, description = "Repository to clone from", argName = "repository")
    public String getRepo() {
        final String value = getValue(REPO);
        return value;
    }

    @Option(opt = DIR, required = false, description = "The optional directory associated with the clone operation. If the directory isn't set, a name associated with the source uri will be used", argName = "directory")
    public String getDir() {
        final String value = getValue(DIR);
        return value;
    }

    @Option(opt = BRANCH, required = false, description = " the initial branch to check out when cloning the repository", argName = "branch")
    public String getBranch() {
        final String value = getValue(BRANCH);
        return value;
    }

    @Override
    protected boolean doExecute() {
        CloneCommand clone = new CloneCommand();
        String repo = getRepo();
        clone.setURI(repo);
        clone.setRemote(GitHelper.getRemote(repo));
        File dir = null;
        try {
            dir = getDirectory(repo);
            if (dir.exists()) {
                File[] children = dir.listFiles();
                if (children != null && children.length > 0) {
                    getLogger().error(MessageFormat.format(
                            "Destination folder {0} already exists and is not an empty directory", dir.getName()));
                    return false;
                }
            }
            clone.setDirectory(dir);
        } catch (URISyntaxException e) {
            getLogger().error(e);
            return false;
        }
        clone.setProgressMonitor(new TextProgressMonitor(new PrintWriter(System.out)));
        if (!askUsername()) {
            getLogger().info(MessageFormat.format("Cloning into {0}...", dir.getName()));
        }
        String branch = getBranch();
        if (branch != null) {
            clone.setBranch(Constants.R_HEADS + branch);
        }
        try {
            URIish uri = new URIish(repo);
            if (GITHUB_HOST.equals(uri.getHost()) && "git".equals(uri.getUser())) {
                if (!prepareSSHFactory()) {
                    return false;
                }
            } else {
                CredentialsProvider credentials = getCredentials(repo);
                if (credentials != null) {
                    clone.setCredentialsProvider(credentials);
                }
            }
            clone.call();
        } catch (JGitInternalException e) {
            delete(dir);
            getLogger().error(e);
            return false;
        } catch (URISyntaxException e) {
            delete(dir);
            getLogger().error(e);
            return false;
        } catch (InvalidRemoteException e) {
            delete(dir);
            getLogger().error(e);
            return false;
        } catch (TransportException e) {
            delete(dir);
            String repoUrl = getRepo();
            if (repoUrl != null && repoUrl.startsWith("https")) {
                if (e.getMessage().endsWith("not authorized")) {
                    setAskUsername(true);
                    return doExecute();
                }
            }
            getLogger().error(e);
            return false;
        } catch (GitAPIException e) {
            delete(dir);
            getLogger().error(e);
            return false;
        }
        updateProject(dir);
        if (GitHelper.ZEND_CLOUD_REMOTE.equals(GitHelper.getRemote(repo))) {
            getLogger().info("The remote name used to keep track of the phpCloud repository is: "
                    + GitHelper.ZEND_CLOUD_REMOTE);
        } else {
            getLogger().info("The remote name used to keep track of the cloned repository is: "
                    + Constants.DEFAULT_REMOTE_NAME);
        }
        return true;
    }

    private void updateProject(File directory) {
        ZendProject project = new ZendProject(directory, new CliMappingLoader());
        try {
            final boolean update = project.update(null);
            if (update) {
                getLogger().debug("Project is updated with deployment descriptor and properties");
            }
        } catch (IllegalArgumentException e) {
            getLogger().error(e);
        }
    }

    protected File getDirectory(String repo) throws URISyntaxException {
        String dir = getDir();
        if (dir != null) {
            File dirFile = new File(dir);
            if (dirFile.isAbsolute()) {
                return dirFile;
            }
            return new File(getCurrentDirectory(), dir);
        }
        URIish uri = new URIish(repo);
        return new File(getCurrentDirectory(), uri.getHumanishName());
    }

    private boolean delete(File file) {
        if (file != null && file.exists() && file.isDirectory()) {
            String[] children = file.list();
            for (int i = 0; i < children.length; i++) {
                boolean result = delete(new File(file, children[i]));
                if (!result) {
                    return false;
                }
            }
        }
        return file.delete();
    }

}