aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Duft2012-07-13 07:06:25 (EDT)
committerRobin Rosenberg2013-01-24 16:03:14 (EST)
commit49480572da5418dfd15737725912bbf73acd5b48 (patch)
tree0f88f4e54b2debe1347f8ab25f725ca208910f8e
parentc22a906c5cdb7ddb23dda06535c2ca8ca60e8988 (diff)
downloadegit-49480572da5418dfd15737725912bbf73acd5b48.zip
egit-49480572da5418dfd15737725912bbf73acd5b48.tar.gz
egit-49480572da5418dfd15737725912bbf73acd5b48.tar.bz2
Introduce a method to find projects containing pathsrefs/changes/44/5344/20
The code searches for IContainer's containing a certain path, by comparing all IProject's and the IWorkspaceRoot location with the given filename. This is much cheaper than calling IWorkspaceRoot.findContainersForLocationURI(). This is required by multiple changes Change-Id: I9c85247d6e0410bc0caefd6a4594373514e16562 Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
-rw-r--r--org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java114
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java79
2 files changed, 193 insertions, 0 deletions
diff --git a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
index bd103f1..e64ae1e 100644
--- a/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
+++ b/org.eclipse.egit.core.test/src/org/eclipse/egit/core/internal/util/ProjectUtilTest.java
@@ -12,6 +12,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
@@ -22,9 +23,13 @@ import static org.mockito.Mockito.when;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.TreeSet;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.egit.core.op.ConnectProviderOperation;
@@ -65,6 +70,115 @@ public class ProjectUtilTest extends GitTestCase {
}
@Test
+ public void testGetProjectsContains() throws Exception {
+ TestProject prj2 = new TestProject(true, "Project-1-sub");
+
+ try {
+ repository.createFile(project.getProject(), "xxx");
+ repository.createFile(project.getProject(), "zzz");
+ repository.createFile(prj2.getProject(), "zzz");
+
+ project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+ prj2.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+
+ IProject[] projectsContaining = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-1/xxx"));
+ IProject[] projectsEmpty = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), Collections.singleton("yyy"));
+ IProject[] projectSelf = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-1"));
+ Set<String> files = new TreeSet<String>();
+ files.add("Project-1/xxx");
+ files.add("Project-1/zzz");
+ IProject[] multiFile = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), files);
+
+ files.clear();
+ files.add("Project-1/xxx");
+ files.add("Project-1-sub/zzz");
+ IProject[] multiProject = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), files);
+ IProject[] nonExistProject = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-2"));
+
+ assertEquals(1, projectsContaining.length);
+ assertEquals(0, projectsEmpty.length);
+ assertEquals(1, projectSelf.length);
+ assertEquals(1, multiFile.length);
+ assertEquals(2, multiProject.length);
+ assertEquals(0, nonExistProject.length);
+
+ IProject p = projectsContaining[0];
+ assertEquals("Project-1", p.getDescription().getName());
+ } finally {
+ prj2.dispose();
+ }
+ }
+
+ @Test
+ public void testGetNestedProjectsContains() throws Exception {
+ TestProject prj2 = new TestProject(true, "Project-1/dir/Project-1-sub");
+
+ try {
+ repository.createFile(project.getProject(), "xxx");
+ repository.createFile(project.getProject(), "zzz");
+ repository.createFile(prj2.getProject(), "zzz");
+
+ project.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+ prj2.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
+
+ IProject[] projectsContaining = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-1/xxx"));
+ IProject[] projectsEmpty = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), Collections.singleton("yyy"));
+ IProject[] projectSelf = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-1"));
+ Set<String> files = new TreeSet<String>();
+ files.add("Project-1/xxx");
+ files.add("Project-1/zzz");
+ IProject[] multiFile = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), files);
+
+ files.clear();
+ files.add("Project-1/dir/Project-1-sub/zzz");
+ files.add("Project-1/xxx");
+ IProject[] multiProject = ProjectUtil.getProjectsContaining(
+ repository.getRepository(), files);
+ IProject[] nonExistProject = ProjectUtil.getProjectsContaining(
+ repository.getRepository(),
+ Collections.singleton("Project-2"));
+
+ assertEquals(1, projectsContaining.length);
+ assertEquals(0, projectsEmpty.length);
+ assertEquals(1, projectSelf.length);
+ assertEquals(1, multiFile.length);
+ assertEquals(2, multiProject.length);
+ assertEquals(0, nonExistProject.length);
+
+ IProject p = projectsContaining[0];
+ assertEquals("Project-1", p.getDescription().getName());
+ } finally {
+ prj2.dispose();
+ }
+ }
+
+ @Test
+ public void testFindContainer() throws Exception {
+ File tmp = new File("/tmp/file");
+ File test1 = new File(project.getProject().getLocation().toFile(), "xxx");
+ File test2 = new File(repository.getRepository().getWorkTree(), "xxx");
+
+ assertNull(ProjectUtil.findContainer(tmp));
+ assertEquals(project.getProject(), ProjectUtil.findContainer(test1));
+ assertEquals(ResourcesPlugin.getWorkspace().getRoot(), ProjectUtil.findContainer(test2));
+ }
+
+ @Test
public void testGetValidOpenProjectsClosedProject() throws Exception {
project.getProject().close(new NullProgressMonitor());
IProject[] projects = ProjectUtil.getValidOpenProjects(repository
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
index 1d9cc84..f50957a 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/util/ProjectUtil.java
@@ -15,14 +15,19 @@ package org.eclipse.egit.core.internal.util;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
+import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -251,6 +256,80 @@ public class ProjectUtil {
}
/**
+ * The method returns all projects containing at least one of the given
+ * paths.
+ *
+ * @param repository
+ * the repository who's working tree is used as base for lookup
+ * @param fileList
+ * the list of files/directories to lookup
+ * @return valid projects containing one of the paths
+ * @throws CoreException
+ */
+ public static IProject[] getProjectsContaining(Repository repository,
+ Collection<String> fileList) throws CoreException {
+ Set<IProject> result = new LinkedHashSet<IProject>();
+ File workTree = repository.getWorkTree();
+
+ for (String member : fileList) {
+ File file = new File(workTree, member);
+
+ IContainer container = findContainer(file);
+ if (container instanceof IProject)
+ result.add((IProject) container);
+ }
+
+ return result.toArray(new IProject[result.size()]);
+ }
+
+ /**
+ * Looks up the IContainer containing the given file, if available. This is
+ * done by path comparison, which is very cheap compared to
+ * IWorkspaceRoot.findContainersForLocationURI()
+ *
+ * @param file
+ * the path to lookup a container for
+ * @return the IContainer (either IProject or IWorkspaceRoot) or
+ * <code>null</code> if not found.
+ */
+ public static IContainer findContainer(File file) {
+ String absFile = file.getAbsolutePath();
+ IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+ IProject[] allProjects = root.getProjects();
+
+ // Sorting makes us look into nested projects first
+ Arrays.sort(allProjects, new Comparator<IProject>() {
+ public int compare(IProject o1, IProject o2) {
+ return -o1.getLocation().toFile()
+ .compareTo(o2.getLocation().toFile());
+ }
+
+ });
+
+ for (IProject prj : allProjects)
+ if (checkContainerMatch(prj, absFile))
+ return prj;
+
+ if (checkContainerMatch(root, absFile))
+ return root;
+
+ return null;
+ }
+
+ private static boolean checkContainerMatch(IContainer container,
+ String absFile) {
+ String absPrj = container.getLocation().toFile().getAbsolutePath();
+ if (absPrj.equals(absFile))
+ return true;
+ if (absPrj.length() < absFile.length()) {
+ char sepChar = absFile.charAt(absPrj.length());
+ if (sepChar == File.separatorChar && absFile.startsWith(absPrj))
+ return true;
+ }
+ return false;
+ }
+
+ /**
* Find directories containing .project files recursively starting at given
* directory
*