View Javadoc
1   /*
2    * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
3    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
4    *
5    * This program and the accompanying materials are made available under the
6    * terms of the Eclipse Distribution License v. 1.0 which is available at
7    * https://www.eclipse.org/org/documents/edl-v10.php.
8    *
9    * SPDX-License-Identifier: BSD-3-Clause
10   */
11  
12  package org.eclipse.jgit.revwalk.filter;
13  
14  import java.io.IOException;
15  import java.util.Collection;
16  
17  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
18  import org.eclipse.jgit.errors.MissingObjectException;
19  import org.eclipse.jgit.internal.JGitText;
20  import org.eclipse.jgit.revwalk.RevCommit;
21  import org.eclipse.jgit.revwalk.RevWalk;
22  
23  /**
24   * Includes a commit only if all subfilters include the same commit.
25   * <p>
26   * Classic shortcut behavior is used, so evaluation of the
27   * {@link org.eclipse.jgit.revwalk.filter.RevFilter#include(RevWalk, RevCommit)}
28   * method stops as soon as a false result is obtained. Applications can improve
29   * filtering performance by placing faster filters that are more likely to
30   * reject a result earlier in the list.
31   */
32  public abstract class AndRevFilter extends RevFilter {
33  	/**
34  	 * Create a filter with two filters, both of which must match.
35  	 *
36  	 * @param a
37  	 *            first filter to test.
38  	 * @param b
39  	 *            second filter to test.
40  	 * @return a filter that must match both input filters.
41  	 */
42  	public static RevFilteref="../../../../../org/eclipse/jgit/revwalk/filter/RevFilter.html#RevFilter">RevFilter../../../../../org/eclipse/jgit/revwalk/filter/RevFilter.html#RevFilter">RevFilter create(RevFilteref="../../../../../org/eclipse/jgit/revwalk/filter/RevFilter.html#RevFilter">RevFilter a, RevFilter b) {
43  		if (a == ALL)
44  			return b;
45  		if (b == ALL)
46  			return a;
47  		return new Binary(a, b);
48  	}
49  
50  	/**
51  	 * Create a filter around many filters, all of which must match.
52  	 *
53  	 * @param list
54  	 *            list of filters to match against. Must contain at least 2
55  	 *            filters.
56  	 * @return a filter that must match all input filters.
57  	 */
58  	public static RevFilter../../../../../org/eclipse/jgit/revwalk/filter/RevFilter.html#RevFilter">RevFilter create(RevFilter[] list) {
59  		if (list.length == 2)
60  			return create(list[0], list[1]);
61  		if (list.length < 2)
62  			throw new IllegalArgumentException(JGitText.get().atLeastTwoFiltersNeeded);
63  		final RevFiltervFilter.html#RevFilter">RevFilter[] subfilters = new RevFilter[list.length];
64  		System.arraycopy(list, 0, subfilters, 0, list.length);
65  		return new List(subfilters);
66  	}
67  
68  	/**
69  	 * Create a filter around many filters, all of which must match.
70  	 *
71  	 * @param list
72  	 *            list of filters to match against. Must contain at least 2
73  	 *            filters.
74  	 * @return a filter that must match all input filters.
75  	 */
76  	public static RevFilter create(Collection<RevFilter> list) {
77  		if (list.size() < 2)
78  			throw new IllegalArgumentException(JGitText.get().atLeastTwoFiltersNeeded);
79  		final RevFiltervFilter.html#RevFilter">RevFilter[] subfilters = new RevFilter[list.size()];
80  		list.toArray(subfilters);
81  		if (subfilters.length == 2)
82  			return create(subfilters[0], subfilters[1]);
83  		return new List(subfilters);
84  	}
85  
86  	private static class Binary extends AndRevFilter {
87  		private final RevFilter a;
88  
89  		private final RevFilter b;
90  
91  		private final boolean requiresCommitBody;
92  
93  		Binary(RevFilter="../../../../../org/eclipse/jgit/revwalk/filter/RevFilter.html#RevFilter">RevFilter one, RevFilter two) {
94  			a = one;
95  			b = two;
96  			requiresCommitBody = a.requiresCommitBody()
97  					|| b.requiresCommitBody();
98  		}
99  
100 		@Override
101 		public boolean include(RevWalk walker, RevCommit c)
102 				throws MissingObjectException, IncorrectObjectTypeException,
103 				IOException {
104 			return a.include(walker, c) && b.include(walker, c);
105 		}
106 
107 		@Override
108 		public boolean requiresCommitBody() {
109 			return requiresCommitBody;
110 		}
111 
112 		@Override
113 		public RevFilter clone() {
114 			return new Binary(a.clone(), b.clone());
115 		}
116 
117 		@SuppressWarnings("nls")
118 		@Override
119 		public String toString() {
120 			return "(" + a.toString() + " AND " + b.toString() + ")"; //$NON-NLS-1$
121 		}
122 	}
123 
124 	private static class List extends AndRevFilter {
125 		private final RevFilter[] subfilters;
126 
127 		private final boolean requiresCommitBody;
128 
129 		List(RevFilter[] list) {
130 			subfilters = list;
131 
132 			boolean rcb = false;
133 			for (RevFilter filter : subfilters)
134 				rcb |= filter.requiresCommitBody();
135 			requiresCommitBody = rcb;
136 		}
137 
138 		@Override
139 		public boolean include(RevWalk walker, RevCommit c)
140 				throws MissingObjectException, IncorrectObjectTypeException,
141 				IOException {
142 			for (RevFilter f : subfilters) {
143 				if (!f.include(walker, c))
144 					return false;
145 			}
146 			return true;
147 		}
148 
149 		@Override
150 		public boolean requiresCommitBody() {
151 			return requiresCommitBody;
152 		}
153 
154 		@Override
155 		public RevFilter clone() {
156 			final RevFilterfilter/RevFilter.html#RevFilter">RevFilter[] s = new RevFilter[subfilters.length];
157 			for (int i = 0; i < s.length; i++)
158 				s[i] = subfilters[i].clone();
159 			return new List(s);
160 		}
161 
162 		@SuppressWarnings("nls")
163 		@Override
164 		public String toString() {
165 			final StringBuilder r = new StringBuilder();
166 			r.append("(");
167 			for (int i = 0; i < subfilters.length; i++) {
168 				if (i > 0)
169 					r.append(" AND ");
170 				r.append(subfilters[i].toString());
171 			}
172 			r.append(")");
173 			return r.toString();
174 		}
175 	}
176 }