Package org.eclipse.egit.core.op

Source Code of org.eclipse.egit.core.op.ConnectProviderOperation

/*******************************************************************************
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2008, Google Inc.
* Copyright (C) 2009, Mykola Nikishov <mn@mn.com.ua>
* Copyright (C) 2013, Matthias Sohn <matthias.sohn@sap.com>
*
* 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.eclipse.egit.core.op;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.GitProvider;
import org.eclipse.egit.core.internal.CoreText;
import org.eclipse.egit.core.internal.trace.GitTraceLocation;
import org.eclipse.egit.core.project.GitProjectData;
import org.eclipse.egit.core.project.RepositoryFinder;
import org.eclipse.egit.core.project.RepositoryMapping;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.RepositoryProvider;

/**
* Connects Eclipse to an existing Git repository
*/
public class ConnectProviderOperation implements IEGitOperation {
  private final Map<IProject, File> projects = new HashMap<IProject, File>();

  /**
   * Create a new connection operation to execute within the workspace.
   * <p>
   * Uses <code>.git</code> as a default relative path to repository.
   * @see #ConnectProviderOperation(IProject, File)
   *
   * @param proj
   *            the project to connect to the Git team provider.
   */
  public ConnectProviderOperation(final IProject proj) {
    this(proj, proj.getLocation().append(Constants.DOT_GIT).toFile());
  }

  /**
   * Create a new connection operation to execute within the workspace.
   *
   * @param proj
   *            the project to connect to the Git team provider.
   * @param pathToRepo
   *            absolute path to the repository
   */
  public ConnectProviderOperation(final IProject proj, File pathToRepo) {
    this.projects.put(proj, pathToRepo);
  }

  /**
   * Create a new connection operation to execute within the workspace.
   *
   * @param projects
   *            the projects to connect to the Git team provider.
   */
  public ConnectProviderOperation(final Map<IProject, File> projects) {
    this.projects.putAll(projects);
  }

  /* (non-Javadoc)
   * @see org.eclipse.egit.core.op.IEGitOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
   */
  public void execute(IProgressMonitor m) throws CoreException {
    IProgressMonitor monitor;
    if (m == null) {
      monitor = new NullProgressMonitor();
    } else {
      monitor = m;
    }

    monitor.beginTask(CoreText.ConnectProviderOperation_connecting,
        100 * projects.size());
    try {

      for (Iterator iterator = projects.keySet().iterator(); iterator.hasNext();) {
        IProject project = (IProject) iterator.next();
        monitor.setTaskName(NLS.bind(
            CoreText.ConnectProviderOperation_ConnectingProject,
            project.getName()));
        // TODO is this the right location?
        if (GitTraceLocation.CORE.isActive())
          GitTraceLocation.getTrace().trace(
              GitTraceLocation.CORE.getLocation(),
              "Locating repository for " + project); //$NON-NLS-1$

        RepositoryFinder finder = new RepositoryFinder(project);
        finder.setFindInChildren(false);
        Collection<RepositoryMapping> repos = finder.find(new SubProgressMonitor(monitor, 40));
        File suggestedRepo = projects.get(project);
        RepositoryMapping actualMapping= findActualRepository(repos, suggestedRepo);
        if (actualMapping != null) {
          GitProjectData projectData = new GitProjectData(project);
          try {
            projectData.setRepositoryMappings(Arrays.asList(actualMapping));
            projectData.store();
            GitProjectData.add(project, projectData);
          } catch (CoreException ce) {
            try {
              GitProjectData.delete(project);
            } catch (IOException e) {
              MultiStatus status = new MultiStatus(
                  Activator.getPluginId(), IStatus.ERROR,
                  e.getMessage(), e);
              status.add(new Status(IStatus.ERROR, Activator
                  .getPluginId(), ce.getMessage(), ce));
              throw new CoreException(status);
            }
            throw ce;
          } catch (RuntimeException ce) {
            try {
              GitProjectData.delete(project);
            } catch (IOException e) {
              MultiStatus status = new MultiStatus(
                  Activator.getPluginId(), IStatus.ERROR,
                  e.getMessage(), e);
              status.add(new Status(IStatus.ERROR, Activator
                  .getPluginId(), ce.getMessage(), ce));
              throw new CoreException(status);
          }
            throw ce;
          }
          RepositoryProvider
              .map(project, GitProvider.class.getName());
          autoIgnoreDerivedResources(project, monitor);
          project.refreshLocal(IResource.DEPTH_INFINITE,
              new SubProgressMonitor(monitor, 50));
          monitor.worked(10);
        } else {
          // TODO is this the right location?
          if (GitTraceLocation.CORE.isActive())
            GitTraceLocation.getTrace().trace(
                GitTraceLocation.CORE.getLocation(),
                "Attempted to share project without repository ignored :" //$NON-NLS-1$
                    + project);
          monitor.worked(60);
        }
      }
    } finally {
      monitor.done();
    }
  }

  private void autoIgnoreDerivedResources(IProject project,
      IProgressMonitor monitor) throws CoreException {
    List<IPath> paths = findDerivedResources(project);
    if (paths.size() > 0) {
      IgnoreOperation ignoreOp = new IgnoreOperation(paths);
      IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
      ignoreOp.execute(subMonitor);
    }
  }

  private List<IPath> findDerivedResources(IContainer c)
      throws CoreException {
    List<IPath> derived = new ArrayList<IPath>();
    IResource[] members = c.members(IContainer.INCLUDE_HIDDEN);
    for (IResource r : members) {
      if (r.isDerived())
        derived.add(r.getLocation());
      else if (r instanceof IContainer)
        derived.addAll(findDerivedResources((IContainer) r));
    }
    return derived;
  }

  /* (non-Javadoc)
   * @see org.eclipse.egit.core.op.IEGitOperation#getSchedulingRule()
   */
  public ISchedulingRule getSchedulingRule() {
    Set<IProject> projectSet = projects.keySet();
    return new MultiRule(projectSet.toArray(new IProject[projectSet.size()]));
  }

  /**
   * @param repos
   *         available repositories
   * @param suggestedRepo
   *         relative path to git repository
   * @return a repository mapping which corresponds to a suggested repository
   *         location, <code>null</code> otherwise
   */
  private RepositoryMapping findActualRepository(
      Collection<RepositoryMapping> repos, File suggestedRepo) {
    for (RepositoryMapping rm : repos) {
      if (rm.getGitDirAbsolutePath().equals(Path.fromOSString(suggestedRepo.getPath())))
        return rm;
    }
    return null;
  }
}
TOP

Related Classes of org.eclipse.egit.core.op.ConnectProviderOperation

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.