Permalink
Browse files

Add new file tree iterator that can adapt into a ContainerTreeIterator

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>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
  • Loading branch information...
torarnv authored and robinrosenberg committed Feb 17, 2009
1 parent 3256cf5 commit a7a354ed0ac06de40e6b196179e9a7427716df33
@@ -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);
+ }
+}
@@ -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);
+ }
+}
@@ -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;
@@ -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;
+ }
}
}

0 comments on commit a7a354e

Please sign in to comment.