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@xxxxxxxxx> --- .../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@xxxxxxxxx> + * + * 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@xxxxxxxxx> + * + * 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html