git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[EGIT PATCH 13/12] Add new file tree iterator that can adapt into a ContainerTreeIterator

From
Tor Arne Vestbø <torarnv@gmail.com>
Date
Feb 17, 2009, 17:51 UTC
Message-ID
<1234893101-23143-1-git-send-email-torarnv@gmail.com>
In-Reply-To
<200902170652.36701.robin.rosenberg@dewire.com>

As the iterator recurses into subtrees it will look for directories that can be mapped using a given workspace root, and if there's a mapping it will return a ContainerTreeIterator instead.

This feature required exposing the underlying file of the FileEntry, as well as making ContainerTreeIterator's constructor that takes a parent iterator public.

Signed-off-by: Tor Arne Vestbø <torarnv@gmail.com>
---
 .../core/T0003_AdaptableFileTreeIteratorTest.java  |   74 +++++++++++++++++
 .../egit/core/AdaptableFileTreeIterator.java       |   87 ++++++++++++++++++++
 .../spearce/egit/core/ContainerTreeIterator.java   |   17 ++++-
 .../spearce/jgit/treewalk/FileTreeIterator.java    |   14 +++-
 4 files changed, 190 insertions(+), 2 deletions(-)
 create mode 100644 org.spearce.egit.core.test/src/org/spearce/egit/core/T0003_AdaptableFileTreeIteratorTest.java
 create mode 100644 org.spearce.egit.core/src/org/spearce/egit/core/AdaptableFileTreeIterator.java
diff --git a/org.spearce.egit.core.test/src/org/spearce/egit/core/T0003_AdaptableFileTreeIteratorTest.java b/org.spearce.egit.core.test/src/org/spearce/egit/core/T0003_AdaptableFileTreeIteratorTest.java
new file mode 100644
index 0000000..1e2fe03
--- /dev/null
+++ b/org.spearce.egit.core.test/src/org/spearce/egit/core/T0003_AdaptableFileTreeIteratorTest.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * See LICENSE for the full license text, also available.
+ *******************************************************************************/
+package org.spearce.egit.core;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.spearce.egit.core.op.ConnectProviderOperation;
+import org.spearce.egit.core.project.RepositoryMapping;
+import org.spearce.egit.core.test.GitTestCase;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.treewalk.TreeWalk;
+import org.spearce.jgit.treewalk.WorkingTreeIterator;
+import org.spearce.jgit.treewalk.filter.PathFilterGroup;
+
+public class T0003_AdaptableFileTreeIteratorTest extends GitTestCase {
+
+	private Repository repository;
+
+	private File repositoryRoot;
+
+	private File file;
+
+	protected void setUp() throws Exception {
+		super.setUp();
+
+		repository = new Repository(gitDir);
+		repositoryRoot = repository.getWorkDir();
+		repository.create();
+
+		file = new File(project.getProject().getLocation().toFile(), "a.txt");
+		final FileWriter fileWriter = new FileWriter(file);
+		fileWriter.write("aaaaaaaaaaa");
+		fileWriter.close();
+
+		final ConnectProviderOperation operation = new ConnectProviderOperation(
+				project.getProject(), null);
+		operation.run(null);
+	}
+
+	public void testFileTreeToContainerAdaptation() throws IOException {
+		final IWorkspaceRoot root = project.getProject().getWorkspace()
+				.getRoot();
+
+		final TreeWalk treeWalk = new TreeWalk(repository);
+		treeWalk.addTree(new AdaptableFileTreeIterator(repositoryRoot, root));
+		treeWalk.setRecursive(true);
+
+		final IFile eclipseFile = project.getProject().getFile(file.getName());
+		final RepositoryMapping mapping = RepositoryMapping
+				.getMapping(eclipseFile);
+		final Set<String> repositoryPaths = Collections.singleton(mapping
+				.getRepoRelativePath(eclipseFile));
+
+		assertTrue(repositoryPaths.size() == 1);
+		treeWalk.setFilter(PathFilterGroup.createFromStrings(repositoryPaths));
+
+		assertTrue(treeWalk.next());
+
+		final WorkingTreeIterator iterator = treeWalk.getTree(1,
+				WorkingTreeIterator.class);
+		assertTrue(iterator instanceof ContainerTreeIterator);
+	}
+}
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/AdaptableFileTreeIterator.java b/org.spearce.egit.core/src/org/spearce/egit/core/AdaptableFileTreeIterator.java
new file mode 100644
index 0000000..61211f6
--- /dev/null
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/AdaptableFileTreeIterator.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (C) 2009, Tor Arne Vestbø <torarnv@gmail.com>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * See LICENSE for the full license text, also available.
+ *******************************************************************************/
+
+package org.spearce.egit.core;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.Path;
+import org.spearce.jgit.errors.IncorrectObjectTypeException;
+import org.spearce.jgit.lib.Repository;
+import org.spearce.jgit.treewalk.AbstractTreeIterator;
+import org.spearce.jgit.treewalk.FileTreeIterator;
+
+/**
+ * Java IO file tree iterator that can adapt to a {@link ContainerTreeIterator}
+ * <p>
+ * The iterator automatically adapts to a {@link ContainerTreeIterator} when
+ * recursing into directories that are accessible from the given workspace root.
+ *
+ * @see org.spearce.jgit.treewalk.FileTreeIterator
+ * @see org.spearce.egit.core.ContainerTreeIterator
+ */
+public class AdaptableFileTreeIterator extends FileTreeIterator {
+
+	IWorkspaceRoot root;
+
+	/**
+	 * Create a new iterator to traverse the given directory and its children
+	 * <p>
+	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
+	 * when encountering directories what can be mapped into the given workspace
+	 * root.
+	 *
+	 * @param path
+	 *            the starting directory. This directory should correspond to
+	 *            the repository root.
+	 * @param workspaceRoot
+	 *            the workspace root to check resource mapping against.
+	 *
+	 */
+	public AdaptableFileTreeIterator(final File path,
+			final IWorkspaceRoot workspaceRoot) {
+		super(path);
+		root = workspaceRoot;
+	}
+
+	/**
+	 * Create a new iterator to traverse a subdirectory.
+	 * <p>
+	 * The iterator will automatically adapt to a {@link ContainerTreeIterator}
+	 * when encountering directories what can be mapped into the given workspace
+	 * root.
+	 *
+	 * @param path
+	 *            the subdirectory. This should be a directory contained within
+	 *            the parent directory.
+	 * @param parent
+	 *            the parent iterator we were created from.
+	 * @param workspaceRoot
+	 *            the workspace root to check resource mapping against.
+	 */
+	protected AdaptableFileTreeIterator(final AdaptableFileTreeIterator parent,
+			File path, final IWorkspaceRoot workspaceRoot) {
+		super(parent, path);
+		root = workspaceRoot;
+	}
+
+	@Override
+	public AbstractTreeIterator createSubtreeIterator(Repository repo)
+			throws IncorrectObjectTypeException, IOException {
+		final File currentFile = ((FileEntry) current()).getFile();
+		final IContainer[] containers = root.findContainersForLocation(new Path(
+				currentFile.getAbsolutePath()));
+		if (containers.length > 0)
+			return new ContainerTreeIterator(this, containers[0]);
+		else
+			return new AdaptableFileTreeIterator(this, currentFile, root);
+	}
+}
diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/ContainerTreeIterator.java b/org.spearce.egit.core/src/org/spearce/egit/core/ContainerTreeIterator.java
index 2403252..de592aa 100644
--- a/org.spearce.egit.core/src/org/spearce/egit/core/ContainerTreeIterator.java
+++ b/org.spearce.egit.core/src/org/spearce/egit/core/ContainerTreeIterator.java
@@ -88,7 +88,22 @@ public ContainerTreeIterator(final IWorkspaceRoot root) {
 		init(entries());
 	}
 
-	private ContainerTreeIterator(final WorkingTreeIterator p,
+	/**
+	 * Construct a new iterator from a container in the workspace, with a given
+	 * parent iterator.
+	 * <p>
+	 * The iterator will support traversal over the named container, but only if
+	 * it is contained within a project which has the Git repository provider
+	 * connected and this resource is mapped into a Git repository. During the
+	 * iteration the paths will be automatically generated to match the proper
+	 * repository paths for this container's children.
+	 * 
+	 * @param p
+	 *            the parent iterator we were created from.
+	 * @param base
+	 *            the part of the workspace the iterator will walk over.
+	 */
+	public ContainerTreeIterator(final WorkingTreeIterator p,
 			final IContainer base) {
 		super(p);
 		node = base;
diff --git a/org.spearce.jgit/src/org/spearce/jgit/treewalk/FileTreeIterator.java b/org.spearce.jgit/src/org/spearce/jgit/treewalk/FileTreeIterator.java
index 2c71151..ef9866a 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/treewalk/FileTreeIterator.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/treewalk/FileTreeIterator.java
@@ -100,7 +100,10 @@ public AbstractTreeIterator createSubtreeIterator(final Repository repo)
 		return r;
 	}
 
-	static class FileEntry extends Entry {
+	/**
+	 * Wrapper for a standard Java IO file
+	 */
+	static public class FileEntry extends Entry {
 		final File file;
 
 		private final FileMode mode;
@@ -151,5 +154,14 @@ public long getLastModified() {
 		public InputStream openInputStream() throws IOException {
 			return new FileInputStream(file);
 		}
+
+		/**
+		 * Get the underlying file of this entry.
+		 * 
+		 * @return the underlying file of this entry
+		 */
+		public File getFile() {
+			return file;
+		}
 	}
 }
-- 
1.6.1.2.309.g2ea3
Previous: Robin RosenbergNext: Tor Arne Vestbø
Message 20 of 21 in “Support customizable label decorations”
  1. 00/12 Support customizable label decorationsTor Arne Vestbø, Feb 11, 2009
  2. 01/12 Add support code to handle plugin property changesTor Arne Vestbø, Feb 11, 2009
  3. 02/12 Use Set instead of array to keep track of change listenersTor Arne Vestbø, Feb 11, 2009
  4. 03/12 Add a specialized team exception for GitTor Arne Vestbø, Feb 11, 2009
  5. 04/12 Add new class ExceptionCollector for grouping exceptionsTor Arne Vestbø, Feb 11, 2009
  6. 05/12 Add new class SWTUtils with helper-methods for creating controlsTor Arne Vestbø, Feb 11, 2009
  7. 06/12 Implement basic customizable label decorations with preferencesTor Arne Vestbø, Feb 11, 2009
  8. 07/12 Add binding for name of the current branchTor Arne Vestbø, Feb 11, 2009
  9. 08/12 Add icon decoration for tracked and untracked resourcesTor Arne Vestbø, Feb 11, 2009
  10. 09/12 Implement icon and text decorations of various resource statesTor Arne Vestbø, Feb 11, 2009
  11. 10/12 Don't decorate every single resource on repository changeTor Arne Vestbø, Feb 11, 2009
  12. 11/12 Expose the underlying resource entries in ContainerTreeIteratorTor Arne Vestbø, Feb 11, 2009
  13. 12/12 Implement label decorations for folders and projectsTor Arne Vestbø, Feb 11, 2009
  14. Robin RosenbergFeb 12, 2009
  15. Robin RosenbergFeb 11, 2009
  16. 08/12 Add icon decoration for tracked and untracked resourcesTor Arne Vestbø, Feb 11, 2009
  17. Robin RosenbergFeb 16, 2009
  18. Tor Arne VestbøFeb 16, 2009
  19. Robin RosenbergFeb 17, 2009
  20. 13/12 Add new file tree iterator that can adapt into a ContainerTreeIteratorTor Arne Vestbø, Feb 17, 2009
  21. 14/12 Allow project decorations regardless of repository root locationTor Arne Vestbø, Feb 17, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.