Capture current selection before opening dialogs in replace actions
[egit/eclipse.git] / org.eclipse.egit.core / src / org / eclipse / egit / core / internal / merge / TreeWalkResourceVariantTreeProvider.java
blob2bc0ea01ad2951ce6c109d4f3d466a024829494b
1 /*******************************************************************************
2 * Copyright (C) 2015, Obeo.
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *******************************************************************************/
9 package org.eclipse.egit.core.internal.merge;
11 import java.io.IOException;
12 import java.util.LinkedHashSet;
13 import java.util.Set;
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.runtime.IPath;
17 import org.eclipse.core.runtime.Path;
18 import org.eclipse.egit.core.internal.storage.TreeParserResourceVariant;
19 import org.eclipse.egit.core.internal.util.ResourceUtil;
20 import org.eclipse.jgit.lib.Repository;
21 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
22 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
23 import org.eclipse.jgit.treewalk.TreeWalk;
24 import org.eclipse.team.core.variants.IResourceVariantTree;
26 /**
27 * This will populate its three {@link IResourceVariantTree} by walking over a
28 * tree walk and caching the IResources it spans.
29 * <p>
30 * Files that are not located within the workspace will be ignored and thus will
31 * not be accessible through the trees created by this provider.
32 * </p>
34 public class TreeWalkResourceVariantTreeProvider implements
35 GitResourceVariantTreeProvider {
36 private final IResourceVariantTree baseTree;
38 private final IResourceVariantTree oursTree;
40 private final IResourceVariantTree theirsTree;
42 private final Set<IResource> roots;
44 private final Set<IResource> knownResources;
46 /**
47 * Constructs the resource variant trees by iterating over the given tree
48 * walk. This TreeWalk must contain at least three trees corresponding to
49 * the three "sides" we need.
50 * <p>
51 * The tree walk will be reset to its initial state when we are done with
52 * the iteration.
53 * </p>
55 * @param repository
56 * The repository this tree walk has been created for.
57 * @param treeWalk
58 * The tree walk to iterate over.
59 * @param baseIndex
60 * Index of the ancestor tree in the given TreeWalk (value
61 * returned by {@link TreeWalk#addTree(AbstractTreeIterator)})
62 * @param ourIndex
63 * Index of our tree in the given TreeWalk (value returned by
64 * {@link TreeWalk#addTree(AbstractTreeIterator)})
65 * @param theirIndex
66 * Index of their tree in the given TreeWalk (value returned by
67 * {@link TreeWalk#addTree(AbstractTreeIterator)})
68 * @throws IOException
69 * if we somehow cannot iterate over the treewalk.
71 public TreeWalkResourceVariantTreeProvider(Repository repository,
72 TreeWalk treeWalk, int baseIndex, int ourIndex, int theirIndex)
73 throws IOException {
74 // Record the initial state of this tree walk before iterating
75 final AbstractTreeIterator[] initialTrees = new AbstractTreeIterator[treeWalk
76 .getTreeCount()];
77 for (int i = 0; i < treeWalk.getTreeCount(); i++) {
78 initialTrees[i] = treeWalk.getTree(i, AbstractTreeIterator.class);
81 final GitResourceVariantCache baseCache = new GitResourceVariantCache();
82 final GitResourceVariantCache theirsCache = new GitResourceVariantCache();
83 final GitResourceVariantCache oursCache = new GitResourceVariantCache();
85 while (treeWalk.next()) {
86 final int modeBase = treeWalk.getRawMode(baseIndex);
87 final int modeOurs = treeWalk.getRawMode(ourIndex);
88 final int modeTheirs = treeWalk.getRawMode(theirIndex);
89 if (modeBase == 0 && modeOurs == 0 && modeTheirs == 0) {
90 // untracked
91 continue;
94 final CanonicalTreeParser base = treeWalk.getTree(baseIndex,
95 CanonicalTreeParser.class);
96 final CanonicalTreeParser ours = treeWalk.getTree(ourIndex,
97 CanonicalTreeParser.class);
98 final CanonicalTreeParser theirs = treeWalk.getTree(theirIndex,
99 CanonicalTreeParser.class);
101 final IPath path = new Path(treeWalk.getPathString());
102 final IResource resource = ResourceUtil
103 .getResourceHandleForLocation(path);
104 // Resource variants only make sense for IResources. Do not consider
105 // files outside of the workspace or otherwise non accessible.
106 if (resource.getProject() != null
107 && resource.getProject().isAccessible()) {
108 if (modeBase != 0) {
109 baseCache.setVariant(resource,
110 TreeParserResourceVariant.create(repository, base));
112 if (modeOurs != 0) {
113 oursCache.setVariant(resource,
114 TreeParserResourceVariant.create(repository, ours));
116 if (modeTheirs != 0) {
117 theirsCache.setVariant(resource,
118 TreeParserResourceVariant.create(repository, theirs));
122 if (treeWalk.isSubtree()) {
123 treeWalk.enterSubtree();
127 // TODO any better way to reset the tree walk after an iteration?
128 treeWalk.reset();
129 for (int i = 0; i < initialTrees.length; i++) {
130 initialTrees[i].reset();
131 treeWalk.addTree(initialTrees[i]);
134 baseTree = new GitCachedResourceVariantTree(baseCache);
135 theirsTree = new GitCachedResourceVariantTree(theirsCache);
136 oursTree = new GitCachedResourceVariantTree(oursCache);
138 roots = new LinkedHashSet<IResource>();
139 roots.addAll(baseCache.getRoots());
140 roots.addAll(oursCache.getRoots());
141 roots.addAll(theirsCache.getRoots());
143 knownResources = new LinkedHashSet<IResource>();
144 knownResources.addAll(baseCache.getKnownResources());
145 knownResources.addAll(oursCache.getKnownResources());
146 knownResources.addAll(theirsCache.getKnownResources());
149 @Override
150 public IResourceVariantTree getBaseTree() {
151 return baseTree;
154 @Override
155 public IResourceVariantTree getRemoteTree() {
156 return theirsTree;
159 @Override
160 public IResourceVariantTree getSourceTree() {
161 return oursTree;
164 @Override
165 public Set<IResource> getKnownResources() {
166 return knownResources;
169 @Override
170 public Set<IResource> getRoots() {
171 return roots;