2 * Copyright (C) 2007 David Watson <dwatson@mimvista.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License, version 2.1, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18 package org
.spearce
.jgit
.lib
;
21 import java
.io
.IOException
;
23 import org
.spearce
.jgit
.lib
.GitIndex
.Entry
;
26 * A class for traversing the index and one or two trees.
28 * A visitor is invoked for executing actions, like figuring out how to merge.
30 public class IndexTreeWalker
{
31 private final Tree mainTree
;
32 private final Tree newTree
;
33 private final File root
;
34 private final IndexTreeVisitor visitor
;
35 private boolean threeTrees
;
38 * Construct a walker for the index and one tree.
45 public IndexTreeWalker(GitIndex index
, Tree tree
, File root
, IndexTreeVisitor visitor
) {
48 this.visitor
= visitor
;
53 indexMembers
= index
.getMembers();
57 * Construct a walker for the index and two trees.
65 public IndexTreeWalker(GitIndex index
, Tree mainTree
, Tree newTree
, File root
, IndexTreeVisitor visitor
) {
66 this.mainTree
= mainTree
;
67 this.newTree
= newTree
;
69 this.visitor
= visitor
;
73 indexMembers
= index
.getMembers();
80 * Actually walk the index tree
84 public void walk() throws IOException
{
85 walk(mainTree
, newTree
, "/");
88 private void walk(Tree tree
, Tree auxTree
, String curDir
) throws IOException
{
89 TreeEntry
[] treeMembers
= tree
== null ?
new TreeEntry
[0] : tree
.members();
90 TreeEntry
[] auxTreeMembers
= auxTree
== null ?
new TreeEntry
[0] : auxTree
.members();
92 int auxTreeCounter
= 0;
94 int curIndexPos
= indexCounter
;
96 while (treeCounter
< treeMembers
.length
||
97 indexCounter
< indexMembers
.length
||
98 auxTreeCounter
< auxTreeMembers
.length
) {
99 TreeEntry h
= treeCounter
< treeMembers
.length ? treeMembers
[treeCounter
] : null;
100 TreeEntry m
= auxTreeCounter
< auxTreeMembers
.length ? auxTreeMembers
[auxTreeCounter
] : null;
101 Entry i
= indexCounter
< indexMembers
.length ? indexMembers
[indexCounter
] : null;
103 String indexName
= i
== null ?
null : i
.getName();
104 String treeName
= h
== null ?
null : h
.getFullName();
105 String auxTreeName
= m
== null ?
null : m
.getFullName();
107 if (treeName
!= null && indexName
!= null && auxTreeName
!= null) {
108 if (eq(h
, i
) && eq(m
, i
)) {
110 visitor
.visitEntry(h
, m
, i
, new File(root
, treeName
));
115 } else if (eq(h
, i
) && lt(h
, m
)) {
117 visitor
.visitEntry(h
, null, i
, new File(root
, treeName
));
121 } else if (eq(h
, m
) && lt(h
, i
)) {
123 if (h
instanceof Tree
) {
124 walk((Tree
)h
, (Tree
)m
, "/" + treeName
);
126 visitor
.visitEntry(h
, m
, null, new File(root
, treeName
));
133 } else if (eq(m
, i
) && lt(i
, h
)) {
135 visitor
.visitEntry(null, m
, i
, new File(root
, indexName
));
139 } else if (lt(h
, i
) && lt(h
, m
)) {
141 if (h
instanceof Tree
) {
142 walk((Tree
) h
, null, "/" + treeName
);
144 visitor
.visitEntry(h
, null, null, new File(root
, treeName
));
148 } else if (lt(m
, i
) && lt(m
, h
)) {
150 if (m
instanceof Tree
) {
151 walk(null, (Tree
) m
, "/" + auxTreeName
);
153 visitor
.visitEntry(null, m
, null, new File(root
, auxTreeName
));
157 } else { // index entry is first
159 visitor
.visitEntry(null, null, i
, new File(root
, indexName
));
163 } else if (treeName
!= null && indexName
!= null) {
166 visitor
.visitEntry(h
, null, i
, new File(root
, indexName
));
167 else visitor
.visitEntry(h
, i
, new File(root
, indexName
));
171 } else if (lt(h
, i
)) {
172 if (h
instanceof Tree
)
173 walk((Tree
) h
, null, "/" + treeName
);
176 visitor
.visitEntry(h
, null, null, new File(root
, treeName
));
177 } else visitor
.visitEntry(h
, null, new File(root
, treeName
));
183 visitor
.visitEntry(null, null, i
, new File(root
, indexName
));
184 } else visitor
.visitEntry(null, i
, new File(root
, indexName
));
188 } else if (treeName
!= null && auxTreeName
!= null) {
190 if (h
instanceof Tree
) {
191 walk((Tree
) h
, (Tree
) m
, "/" + treeName
);
193 visitor
.visitEntry(h
, m
, null, new File(root
, treeName
));
198 } else if (lt(h
, m
)) {
199 if (h
instanceof Tree
) {
200 walk((Tree
) h
, null, "/" + treeName
);
202 visitor
.visitEntry(h
, null, null, new File(root
, treeName
));
207 if (m
instanceof Tree
) {
208 walk(null, (Tree
) m
, "/" + auxTreeName
);
210 visitor
.visitEntry(null, m
, null, new File("/" + auxTreeName
));
216 } else if (indexName
!= null && auxTreeName
!= null) {
218 visitor
.visitEntry(null, m
, i
, new File(root
, indexName
));
222 } else if (lt(m
, i
)) {
223 if (m
instanceof Tree
)
224 walk(null, (Tree
) m
, "/" + auxTreeName
);
226 visitor
.visitEntry(null, m
, null, new File(root
, auxTreeName
));
231 visitor
.visitEntry(null, null, i
, new File(root
, indexName
));
235 } else if (treeName
!= null) {
236 if (h
instanceof Tree
) {
237 walk((Tree
) h
, null, "/" + treeName
);
238 } else if (threeTrees
)
239 visitor
.visitEntry(h
, null, null, new File(root
, treeName
));
240 else visitor
.visitEntry(h
, null, new File(root
, treeName
));
243 } else if (auxTreeName
!= null) {
244 if (m
instanceof Tree
) {
245 walk(null, (Tree
)m
, "/" + auxTreeName
);
246 } else visitor
.visitEntry(null, m
, null, new File(root
, auxTreeName
));
249 } else if (indexName
!= null) {
250 // need to check if we're done with this tree
251 String curDirNoSlash
= curDir
.substring(1);
252 if (!indexName
.startsWith(curDirNoSlash
+ "/") && curDirNoSlash
.length() != 0)
256 visitor
.visitEntry(null, null, i
, new File(root
, indexName
));
257 else visitor
.visitEntry(null, i
, new File(root
, indexName
));
263 visitor
.finishVisitTree(tree
, auxTree
, indexCounter
- curIndexPos
,
264 curDir
.substring(1));
266 visitor
.finishVisitTree(tree
, indexCounter
- curIndexPos
, curDir
);
270 static boolean lt(TreeEntry h
, Entry i
) {
271 return compare(h
, i
) < 0;
274 static boolean lt(Entry i
, TreeEntry t
) {
275 return compare(t
, i
) > 0;
278 static boolean lt(TreeEntry h
, TreeEntry m
) {
279 return compare(h
, m
) < 0;
282 static boolean eq(TreeEntry t1
, TreeEntry t2
) {
283 return compare(t1
, t2
) == 0;
286 static boolean eq(TreeEntry t1
, Entry e
) {
287 return compare(t1
, e
) == 0;
290 static int compare(TreeEntry t
, Entry i
) {
291 return Tree
.compareNames(t
.getFullNameUTF8(), i
.getNameUTF8(), TreeEntry
.lastChar(t
), TreeEntry
.lastChar(i
));
294 static int compare(TreeEntry t1
, TreeEntry t2
) {
295 return Tree
.compareNames(t1
.getNameUTF8(), t2
.getNameUTF8(), TreeEntry
.lastChar(t1
), TreeEntry
.lastChar(t2
));