Package de.abg.reichert.joerg.eclipsetools.workingsets.internal

Source Code of de.abg.reichert.joerg.eclipsetools.workingsets.internal.CustomGitProjectSetCapability$ProjectReferenceComparator

package de.abg.reichert.joerg.eclipsetools.workingsets.internal;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.CoreText;
import org.eclipse.egit.core.op.CloneOperation;
import org.eclipse.egit.core.op.ConnectProviderOperation;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.transport.URIish;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.team.core.ProjectSetCapability;
import org.eclipse.team.core.ProjectSetSerializationContext;
import org.eclipse.team.core.TeamException;
import org.eclipse.ui.PlatformUI;

public class CustomGitProjectSetCapability extends ProjectSetCapability {

  private static final String SEPARATOR = ","; //$NON-NLS-1$
  private static final String VERSION = "1.0"; //$NON-NLS-1$

  private Shell shell;

  public CustomGitProjectSetCapability(Shell shell) {
    this.shell = shell;
  }

  private static final class ProjectReferenceComparator implements
      Comparator<ProjectReference>, Serializable {
    private static final long serialVersionUID = 1L;

    public int compare(ProjectReference o1, ProjectReference o2) {
      final boolean reposEqual = o1.repository.equals(o2.repository);
      final boolean branchesEqual = o1.branch.equals(o2.branch);
      final boolean projectDirsEqual = o1.projectDir
          .equals(o2.projectDir);
      return reposEqual && branchesEqual && projectDirsEqual ? 0 : 1;
    }
  }

  private static final class ProjectReference {

    private static final String DEFAULT_BRANCH = Constants.MASTER;

    /**
     * a relative path (from the repository root) to a project
     */
    String projectDir;

    /**
     * <code>repository</code> parameter
     */
    URIish repository;

    /**
     * the remote branch that will be checked out, see <code>--branch</code>
     * option
     */
    String branch = DEFAULT_BRANCH;

    @SuppressWarnings("boxing")
    ProjectReference(final String reference) throws URISyntaxException,
        IllegalArgumentException {
      final String[] tokens = reference.split(Pattern.quote(SEPARATOR));
      if (tokens.length != 4)
        throw new IllegalArgumentException("InvalidTokensCount: "
            + tokens.length + " for " + tokens);

      this.repository = new URIish(tokens[1]);
      if (!"".equals(tokens[2])) //$NON-NLS-1$
        this.branch = tokens[2];
      this.projectDir = tokens[3];
    }
  }

  @Override
  public String[] asReference(IProject[] projects,
      ProjectSetSerializationContext context, IProgressMonitor monitor)
      throws TeamException {
    String[] references = new String[projects.length];
    for (int i = 0; i < projects.length; i++)
      references[i] = asReference(projects[i]);
    return references;
  }

  private String asReference(IProject project) throws TeamException {
    RepositoryMapping mapping = RepositoryMapping.getMapping(project);
    String branch;
    try {
      branch = mapping.getRepository().getBranch();
    } catch (IOException e) {
      throw new TeamException(NLS.bind(
          CoreText.GitProjectSetCapability_ExportCouldNotGetBranch,
          project.getName()));
    }
    StoredConfig config = mapping.getRepository().getConfig();
    String remote = config.getString(ConfigConstants.CONFIG_BRANCH_SECTION,
        branch, ConfigConstants.CONFIG_KEY_REMOTE);
    String url = config.getString(ConfigConstants.CONFIG_REMOTE_SECTION,
        remote, ConfigConstants.CONFIG_KEY_URL);
    if (url == null)
      throw new TeamException(NLS.bind(
          CoreText.GitProjectSetCapability_ExportNoRemote,
          project.getName()));

    String projectPath = mapping.getRepoRelativePath(project);
    if (projectPath.equals("")) //$NON-NLS-1$
      projectPath = "."; //$NON-NLS-1$

    StringBuilder sb = new StringBuilder();

    sb.append(VERSION);
    sb.append(SEPARATOR);
    sb.append(url);
    sb.append(SEPARATOR);
    sb.append(branch);
    sb.append(SEPARATOR);
    sb.append(projectPath);

    return sb.toString();
  }

  @Override
  public IProject[] addToWorkspace(final String[] referenceStrings,
      final ProjectSetSerializationContext context,
      final IProgressMonitor monitor) throws TeamException {
    final Map<URIish, Map<String, Set<ProjectReference>>> repositories = new LinkedHashMap<URIish, Map<String, Set<ProjectReference>>>();
    getRepositories(referenceStrings, repositories);
    final ArrayList<IProject> importedProjects = new ArrayList<IProject>();
    for (final Map.Entry<URIish, Map<String, Set<ProjectReference>>> entry : repositories
        .entrySet()) {
      final URIish gitUrl = entry.getKey();
      final Map<String, Set<ProjectReference>> branches = entry
          .getValue();

      for (final Map.Entry<String, Set<ProjectReference>> branchEntry : branches
          .entrySet()) {
        final String branch = branchEntry.getKey();
        final Set<ProjectReference> projects = branchEntry.getValue();

        try {
          final IPath workDir = getWorkingDir(gitUrl, branch,
              branches.keySet());
          boolean exists = isExistingWorkingDirectory(gitUrl,
              projects, workDir);

          int timeout = 60;
          String refName = Constants.R_HEADS + branch;

          clone(monitor, gitUrl, workDir, timeout, refName, exists);

          final File repositoryPath = getRepositoryPath(workDir);

          Activator.getDefault().getRepositoryUtil()
              .addConfiguredRepository(repositoryPath);

          // import projects from the current repository to workspace
          importProjects(workDir, projects, importedProjects,
              repositoryPath, monitor, exists);
        } catch (final InvocationTargetException e) {
          throw TeamException.asTeamException(e);
        } catch (final CoreException e) {
          throw TeamException.asTeamException(e);
        } catch (final InterruptedException e) {
          // was canceled by user
          return new IProject[0];
        }
      }
    }
    final IProject[] result = importedProjects
        .toArray(new IProject[importedProjects.size()]);
    return result;
  }

  protected File getRepositoryPath(final IPath workDir) {
    return workDir.append(Constants.DOT_GIT_EXT).toFile();
  }

  protected boolean isExistingWorkingDirectory(final URIish gitUrl,
      final Set<ProjectReference> projects, final IPath workDir)
      throws TeamException {
    return workDir.toFile().exists();
  }

  protected void importProjects(final IPath workDir,
      final Set<ProjectReference> projects,
      final ArrayList<IProject> importedProjects,
      final File repositoryPath, final IProgressMonitor monitor,
      boolean exists) throws CoreException {
    final IWorkspace workspace = ResourcesPlugin.getWorkspace();
    final IWorkspaceRoot root = workspace.getRoot();
    for (final ProjectReference projectToImport : projects) {
      final IPath projectDir = workDir.append(projectToImport.projectDir);
      final IProjectDescription projectDescription = workspace
          .loadProjectDescription(projectDir
              .append(IProjectDescription.DESCRIPTION_FILE_NAME));
      final IProject project = root.getProject(projectDescription
          .getName());
      createProject(monitor, projectDescription, project, exists);
      importedProjects.add(project);

      project.open(monitor);
      connectProject(monitor, repositoryPath, project);
    }
  }

  protected void connectProject(final IProgressMonitor monitor,
      final File repositoryPath, final IProject project)
      throws CoreException {
    final ConnectProviderOperation connectProviderOperation = new ConnectProviderOperation(
        project, repositoryPath);
    connectProviderOperation.execute(monitor);
  }

  protected void createProject(final IProgressMonitor monitor,
      final IProjectDescription projectDescription,
      final IProject project, boolean exists) throws CoreException {
    if(!project.exists()) {
      project.create(projectDescription, monitor);
    }
  }

  protected void clone(final IProgressMonitor monitor, final URIish gitUrl,
      final IPath workDir, int timeout, String refName, boolean exists)
      throws InvocationTargetException, InterruptedException {
    // TODO only clone if not exists
    if (!exists) {
      final CloneOperation cloneOperation = new CloneOperation(gitUrl,
          true, null, workDir.toFile(), refName,
          Constants.DEFAULT_REMOTE_NAME, timeout);
      cloneOperation.run(monitor);
    }
  }

  private void getRepositories(final String[] referenceStrings,
      final Map<URIish, Map<String, Set<ProjectReference>>> repositories)
      throws TeamException {
    for (final String reference : referenceStrings) {
      try {
        final ProjectReference projectReference = new ProjectReference(
            reference);
        Map<String, Set<ProjectReference>> repositoryBranches = repositories
            .get(projectReference.repository);
        if (repositoryBranches == null) {
          repositoryBranches = new HashMap<String, Set<ProjectReference>>();
          repositories.put(projectReference.repository,
              repositoryBranches);
        }
        Set<ProjectReference> projectReferences = repositoryBranches
            .get(projectReference.branch);
        if (projectReferences == null) {
          projectReferences = new TreeSet<ProjectReference>(
              new ProjectReferenceComparator());
          repositoryBranches.put(projectReference.branch,
              projectReferences);
        }

        projectReferences.add(projectReference);
      } catch (final IllegalArgumentException e) {
        throw new TeamException(reference, e);
      } catch (final URISyntaxException e) {
        throw new TeamException(reference, e);
      }
    }
  }

  /**
   * @param gitUrl
   * @param branch
   *            the branch to check out
   * @param allBranches
   *            all branches which should be checked out for this gitUrl
   * @return the directory where the project should be checked out
   */

  private String absPath = null;

  private IPath getWorkingDir(URIish gitUrl, String branch,
      Set<String> allBranches) {
    absPath = null;
    if (getShell() != null) {
      getShell().getDisplay().syncExec(new Runnable() {
        @Override
        public void run() {
          DirectoryDialog directoryDialog = new DirectoryDialog(
              Display.getDefault().getActiveShell());
          absPath = directoryDialog.open();
        }
      });

    }
    final IPath workspaceLocation;
    if (absPath != null && new File(absPath).exists()) {
      workspaceLocation = Path.fromOSString(absPath);
    } else {
      workspaceLocation = ResourcesPlugin.getWorkspace().getRoot()
          .getRawLocation();
    }
    String[] children = workspaceLocation.toFile().list();
    boolean containsGit = false;
    if(children != null) {
      for(String child : children) {
        if(".git".equals(child)) {
          containsGit = true;
          break;   
        }
      }
    }
   
    final String humanishName = gitUrl.getHumanishName();
    final IPath workDir;
    if(!containsGit) {
      String extendedName;
      if (allBranches.size() == 1 || branch.equals(Constants.MASTER))
        extendedName = humanishName;
      else
        extendedName = humanishName + "_" + branch; //$NON-NLS-1$
      workDir = workspaceLocation.append(extendedName);
    } else {
      workDir = workspaceLocation;
    }
    return workDir;
  }

  protected Shell getShell() {
    return shell;
  }

}
TOP

Related Classes of de.abg.reichert.joerg.eclipsetools.workingsets.internal.CustomGitProjectSetCapability$ProjectReferenceComparator

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.