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 org.eclipse.jgit.dircache.DirCache} as part of a 58 * <code>TreeWalk</code>. 59 * <p> 60 * Like {@link org.eclipse.jgit.dircache.DirCacheIterator} this iterator allows 61 * a DirCache to be used in parallel with other sorts of iterators in a 62 * TreeWalk. However any entry which appears in the source DirCache and which is 63 * skipped by the TreeFilter is automatically copied into 64 * {@link org.eclipse.jgit.dircache.DirCacheBuilder}, thus retaining it in the 65 * newly updated index. 66 * <p> 67 * This iterator is suitable for update processes, or even a simple delete 68 * algorithm. For example deleting a path: 69 * 70 * <pre> 71 * final DirCache dirc = db.lockDirCache(); 72 * final DirCacheBuilder edit = dirc.builder(); 73 * 74 * final TreeWalk walk = new TreeWalk(db); 75 * walk.reset(); 76 * walk.setRecursive(true); 77 * walk.setFilter(PathFilter.create("name/to/remove")); 78 * walk.addTree(new DirCacheBuildIterator(edit)); 79 * 80 * while (walk.next()) 81 * ; // do nothing on a match as we want to remove matches 82 * edit.commit(); 83 * </pre> 84 */ 85 public class DirCacheBuildIterator extends DirCacheIterator { 86 private final DirCacheBuilder builder; 87 88 /** 89 * Create a new iterator for an already loaded DirCache instance. 90 * <p> 91 * The iterator implementation may copy part of the cache's data during 92 * construction, so the cache must be read in prior to creating the 93 * iterator. 94 * 95 * @param dcb 96 * the cache builder for the cache to walk. The cache must be 97 * already loaded into memory. 98 */ 99 public DirCacheBuildIterator(DirCacheBuilder dcb) { 100 super(dcb.getDirCache()); 101 builder = dcb; 102 } 103 104 DirCacheBuildIterator(final DirCacheBuildIterator p, 105 final DirCacheTree dct) { 106 super(p, dct); 107 builder = p.builder; 108 } 109 110 /** {@inheritDoc} */ 111 @Override 112 public AbstractTreeIterator createSubtreeIterator(ObjectReader reader) 113 throws IncorrectObjectTypeException, IOException { 114 if (currentSubtree == null) 115 throw new IncorrectObjectTypeException(getEntryObjectId(), 116 Constants.TYPE_TREE); 117 return new DirCacheBuildIterator(this, currentSubtree); 118 } 119 120 /** {@inheritDoc} */ 121 @Override 122 public void skip() throws CorruptObjectException { 123 if (currentSubtree != null) 124 builder.keep(ptr, currentSubtree.getEntrySpan()); 125 else 126 builder.keep(ptr, 1); 127 next(1); 128 } 129 130 /** {@inheritDoc} */ 131 @Override 132 public void stopWalk() { 133 final int cur = ptr; 134 final int cnt = cache.getEntryCount(); 135 if (cur < cnt) 136 builder.keep(cur, cnt - cur); 137 } 138 139 /** {@inheritDoc} */ 140 @Override 141 protected boolean needsStopWalk() { 142 return ptr < cache.getEntryCount(); 143 } 144 }