1 /* 2 * Copyright (C) 2010, Google Inc. 3 * and other copyright owners as documented in the project's IP log. 4 * 5 * This program and the accompanying materials are made available 6 * under the terms of the Eclipse Distribution License v1.0 which 7 * accompanies this distribution, is reproduced below, and is 8 * available at http://www.eclipse.org/org/documents/edl-v10.php 9 * 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials provided 22 * with the distribution. 23 * 24 * - Neither the name of the Eclipse Foundation, Inc. nor the 25 * names of its contributors may be used to endorse or promote 26 * products derived from this software without specific prior 27 * written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 30 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 31 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 32 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 33 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 34 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 36 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 38 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 41 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 */ 43 44 package org.eclipse.jgit.revwalk; 45 46 import java.io.IOException; 47 48 import org.eclipse.jgit.diff.DiffConfig; 49 import org.eclipse.jgit.errors.IncorrectObjectTypeException; 50 import org.eclipse.jgit.errors.MissingObjectException; 51 import org.eclipse.jgit.treewalk.TreeWalk; 52 import org.eclipse.jgit.treewalk.filter.PathFilter; 53 import org.eclipse.jgit.treewalk.filter.TreeFilter; 54 55 /** 56 * Updates the internal path filter to follow copy/renames. 57 * <p> 58 * This is a special filter that performs {@code AND(path, ANY_DIFF)}, but also 59 * triggers rename detection so that the path node is updated to include a prior 60 * file name as the RevWalk traverses history. 61 * 62 * The renames found will be reported to a 63 * {@link org.eclipse.jgit.revwalk.RenameCallback} if one is set. 64 * <p> 65 * Results with this filter are unpredictable if the path being followed is a 66 * subdirectory. 67 */ 68 public class FollowFilter extends TreeFilter { 69 /** 70 * Create a new tree filter for a user supplied path. 71 * <p> 72 * Path strings are relative to the root of the repository. If the user's 73 * input should be assumed relative to a subdirectory of the repository the 74 * caller must prepend the subdirectory's path prior to creating the filter. 75 * <p> 76 * Path strings use '/' to delimit directories on all platforms. 77 * 78 * @param path 79 * the path to filter on. Must not be the empty string. All 80 * trailing '/' characters will be trimmed before string's length 81 * is checked or is used as part of the constructed filter. 82 * @param cfg 83 * diff config specifying rename detection options. 84 * @return a new filter for the requested path. 85 * @throws java.lang.IllegalArgumentException 86 * the path supplied was the empty string. 87 * @since 3.0 88 */ 89 public static FollowFilter create(String path, DiffConfig cfg) { 90 return new FollowFilter(PathFilter.create(path), cfg); 91 } 92 93 private final PathFilter path; 94 final DiffConfig cfg; 95 96 private RenameCallback renameCallback; 97 98 FollowFilter(PathFilter path, DiffConfig cfg) { 99 this.path = path; 100 this.cfg = cfg; 101 } 102 103 /** @return the path this filter matches. */ 104 /** 105 * Get the path this filter matches. 106 * 107 * @return the path this filter matches. 108 */ 109 public String getPath() { 110 return path.getPath(); 111 } 112 113 /** {@inheritDoc} */ 114 @Override 115 public boolean include(TreeWalk walker) 116 throws MissingObjectException, IncorrectObjectTypeException, 117 IOException { 118 return path.include(walker) && ANY_DIFF.include(walker); 119 } 120 121 /** {@inheritDoc} */ 122 @Override 123 public boolean shouldBeRecursive() { 124 return path.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive(); 125 } 126 127 /** {@inheritDoc} */ 128 @Override 129 public TreeFilter clone() { 130 return new FollowFilter(path.clone(), cfg); 131 } 132 133 /** {@inheritDoc} */ 134 @SuppressWarnings("nls") 135 @Override 136 public String toString() { 137 return "(FOLLOW(" + path.toString() + ")" // 138 + " AND " // 139 + ANY_DIFF.toString() + ")"; 140 } 141 142 /** 143 * Get the callback to which renames are reported. 144 * 145 * @return the callback to which renames are reported, or <code>null</code> 146 * if none 147 */ 148 public RenameCallback getRenameCallback() { 149 return renameCallback; 150 } 151 152 /** 153 * Sets the callback to which renames shall be reported. 154 * 155 * @param callback 156 * the callback to use 157 */ 158 public void setRenameCallback(RenameCallback callback) { 159 renameCallback = callback; 160 } 161 }