1 /*
2 * Copyright (C) 2008-2009, Google Inc.
3 * Copyright (C) 2009, Robin Rosenberg <robin.rosenberg@dewire.com>
4 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
5 * and other copyright owners as documented in the project's IP log.
6 *
7 * This program and the accompanying materials are made available
8 * under the terms of the Eclipse Distribution License v1.0 which
9 * accompanies this distribution, is reproduced below, and is
10 * available at http://www.eclipse.org/org/documents/edl-v10.php
11 *
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * - Redistributions in binary form must reproduce the above
22 * copyright notice, this list of conditions and the following
23 * disclaimer in the documentation and/or other materials provided
24 * with the distribution.
25 *
26 * - Neither the name of the Eclipse Foundation, Inc. nor the
27 * names of its contributors may be used to endorse or promote
28 * products derived from this software without specific prior
29 * written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
34 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
36 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
43 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 */
45
46 package org.eclipse.jgit.dircache;
47
48 import java.io.IOException;
49
50 import org.eclipse.jgit.errors.CorruptObjectException;
51 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
52 import org.eclipse.jgit.lib.Constants;
53 import org.eclipse.jgit.lib.ObjectReader;
54 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
55
56 /**
57 * Iterate and update a {@link DirCache} as part of a <code>TreeWalk</code>.
58 * <p>
59 * Like {@link DirCacheIterator} this iterator allows a DirCache to be used in
60 * parallel with other sorts of iterators in a TreeWalk. However any entry which
61 * appears in the source DirCache and which is skipped by the TreeFilter is
62 * automatically copied into {@link DirCacheBuilder}, thus retaining it in the
63 * newly updated index.
64 * <p>
65 * This iterator is suitable for update processes, or even a simple delete
66 * algorithm. For example deleting a path:
67 *
68 * <pre>
69 * final DirCache dirc = db.lockDirCache();
70 * final DirCacheBuilder edit = dirc.builder();
71 *
72 * final TreeWalk walk = new TreeWalk(db);
73 * walk.reset();
74 * walk.setRecursive(true);
75 * walk.setFilter(PathFilter.create("name/to/remove"));
76 * walk.addTree(new DirCacheBuildIterator(edit));
77 *
78 * while (walk.next())
79 * ; // do nothing on a match as we want to remove matches
80 * edit.commit();
81 * </pre>
82 */
83 public class DirCacheBuildIterator extends DirCacheIterator {
84 private final DirCacheBuilder builder;
85
86 /**
87 * Create a new iterator for an already loaded DirCache instance.
88 * <p>
89 * The iterator implementation may copy part of the cache's data during
90 * construction, so the cache must be read in prior to creating the
91 * iterator.
92 *
93 * @param dcb
94 * the cache builder for the cache to walk. The cache must be
95 * already loaded into memory.
96 */
97 public DirCacheBuildIterator(final DirCacheBuilder dcb) {
98 super(dcb.getDirCache());
99 builder = dcb;
100 }
101
102 DirCacheBuildIterator(final DirCacheBuildIterator p,
103 final DirCacheTree dct) {
104 super(p, dct);
105 builder = p.builder;
106 }
107
108 @Override
109 public AbstractTreeIterator createSubtreeIterator(final ObjectReader reader)
110 throws IncorrectObjectTypeException, IOException {
111 if (currentSubtree == null)
112 throw new IncorrectObjectTypeException(getEntryObjectId(),
113 Constants.TYPE_TREE);
114 return new DirCacheBuildIterator(this, currentSubtree);
115 }
116
117 @Override
118 public void skip() throws CorruptObjectException {
119 if (currentSubtree != null)
120 builder.keep(ptr, currentSubtree.getEntrySpan());
121 else
122 builder.keep(ptr, 1);
123 next(1);
124 }
125
126 @Override
127 public void stopWalk() {
128 final int cur = ptr;
129 final int cnt = cache.getEntryCount();
130 if (cur < cnt)
131 builder.keep(cur, cnt - cur);
132 }
133
134 @Override
135 protected boolean needsStopWalk() {
136 return ptr < cache.getEntryCount();
137 }
138 }