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 }