View Javadoc
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> and others
5    *
6    * This program and the accompanying materials are made available under the
7    * terms of the Eclipse Distribution License v. 1.0 which is available at
8    * https://www.eclipse.org/org/documents/edl-v10.php.
9    *
10   * SPDX-License-Identifier: BSD-3-Clause
11   */
12  
13  package org.eclipse.jgit.dircache;
14  
15  import java.io.IOException;
16  
17  import org.eclipse.jgit.errors.CorruptObjectException;
18  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
19  import org.eclipse.jgit.lib.Constants;
20  import org.eclipse.jgit.lib.ObjectReader;
21  import org.eclipse.jgit.treewalk.AbstractTreeIterator;
22  
23  /**
24   * Iterate and update a {@link org.eclipse.jgit.dircache.DirCache} as part of a
25   * <code>TreeWalk</code>.
26   * <p>
27   * Like {@link org.eclipse.jgit.dircache.DirCacheIterator} this iterator allows
28   * a DirCache to be used in parallel with other sorts of iterators in a
29   * TreeWalk. However any entry which appears in the source DirCache and which is
30   * skipped by the TreeFilter is automatically copied into
31   * {@link org.eclipse.jgit.dircache.DirCacheBuilder}, thus retaining it in the
32   * newly updated index.
33   * <p>
34   * This iterator is suitable for update processes, or even a simple delete
35   * algorithm. For example deleting a path:
36   *
37   * <pre>
38   * final DirCache dirc = db.lockDirCache();
39   * final DirCacheBuilder edit = dirc.builder();
40   *
41   * final TreeWalk walk = new TreeWalk(db);
42   * walk.reset();
43   * walk.setRecursive(true);
44   * walk.setFilter(PathFilter.create(&quot;name/to/remove&quot;));
45   * walk.addTree(new DirCacheBuildIterator(edit));
46   *
47   * while (walk.next())
48   * 	; // do nothing on a match as we want to remove matches
49   * edit.commit();
50   * </pre>
51   */
52  public class DirCacheBuildIterator extends DirCacheIterator {
53  	private final DirCacheBuilder builder;
54  
55  	/**
56  	 * Create a new iterator for an already loaded DirCache instance.
57  	 * <p>
58  	 * The iterator implementation may copy part of the cache's data during
59  	 * construction, so the cache must be read in prior to creating the
60  	 * iterator.
61  	 *
62  	 * @param dcb
63  	 *            the cache builder for the cache to walk. The cache must be
64  	 *            already loaded into memory.
65  	 */
66  	public DirCacheBuildIterator(DirCacheBuilder dcb) {
67  		super(dcb.getDirCache());
68  		builder = dcb;
69  	}
70  
71  	DirCacheBuildIterator(final DirCacheBuildIterator p,
72  			final DirCacheTree dct) {
73  		super(p, dct);
74  		builder = p.builder;
75  	}
76  
77  	/** {@inheritDoc} */
78  	@Override
79  	public AbstractTreeIterator createSubtreeIterator(ObjectReader reader)
80  			throws IncorrectObjectTypeException, IOException {
81  		if (currentSubtree == null)
82  			throw new IncorrectObjectTypeException(getEntryObjectId(),
83  					Constants.TYPE_TREE);
84  		return new DirCacheBuildIterator(this, currentSubtree);
85  	}
86  
87  	/** {@inheritDoc} */
88  	@Override
89  	public void skip() throws CorruptObjectException {
90  		if (currentSubtree != null)
91  			builder.keep(ptr, currentSubtree.getEntrySpan());
92  		else
93  			builder.keep(ptr, 1);
94  		next(1);
95  	}
96  
97  	/** {@inheritDoc} */
98  	@Override
99  	public void stopWalk() {
100 		final int cur = ptr;
101 		final int cnt = cache.getEntryCount();
102 		if (cur < cnt)
103 			builder.keep(cur, cnt - cur);
104 	}
105 
106 	/** {@inheritDoc} */
107 	@Override
108 	protected boolean needsStopWalk() {
109 		return ptr < cache.getEntryCount();
110 	}
111 }