1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.ignore;
11
12 import static org.eclipse.jgit.ignore.IMatcher.NO_MATCH;
13 import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern;
14 import static org.eclipse.jgit.ignore.internal.Strings.stripTrailing;
15 import static org.eclipse.jgit.ignore.internal.Strings.stripTrailingWhitespace;
16
17 import org.eclipse.jgit.errors.InvalidPatternException;
18 import org.eclipse.jgit.ignore.internal.PathMatcher;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22
23
24
25
26
27
28
29
30 public class FastIgnoreRule {
31 private static final Logger LOG = LoggerFactory
32 .getLogger(FastIgnoreRule.class);
33
34
35
36
37 public static final char PATH_SEPARATOR = '/';
38
39 private final IMatcher matcher;
40
41 private final boolean inverse;
42
43 private final boolean dirOnly;
44
45
46
47
48
49
50
51
52
53
54 public FastIgnoreRule(String pattern) {
55 if (pattern == null)
56 throw new IllegalArgumentException("Pattern must not be null!");
57 if (pattern.length() == 0) {
58 dirOnly = false;
59 inverse = false;
60 this.matcher = NO_MATCH;
61 return;
62 }
63 inverse = pattern.charAt(0) == '!';
64 if (inverse) {
65 pattern = pattern.substring(1);
66 if (pattern.length() == 0) {
67 dirOnly = false;
68 this.matcher = NO_MATCH;
69 return;
70 }
71 }
72 if (pattern.charAt(0) == '#') {
73 this.matcher = NO_MATCH;
74 dirOnly = false;
75 return;
76 }
77 if (pattern.charAt(0) == '\\' && pattern.length() > 1) {
78 char next = pattern.charAt(1);
79 if (next == '!' || next == '#') {
80
81 pattern = pattern.substring(1);
82 }
83 }
84 dirOnly = isDirectoryPattern(pattern);
85 if (dirOnly) {
86 pattern = stripTrailingWhitespace(pattern);
87 pattern = stripTrailing(pattern, PATH_SEPARATOR);
88 if (pattern.length() == 0) {
89 this.matcher = NO_MATCH;
90 return;
91 }
92 }
93 IMatcher m;
94 try {
95 m = PathMatcher.createPathMatcher(pattern,
96 Character.valueOf(PATH_SEPARATOR), dirOnly);
97 } catch (InvalidPatternException e) {
98 m = NO_MATCH;
99 LOG.error(e.getMessage(), e);
100 }
101 this.matcher = m;
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public boolean isMatch(String path, boolean directory) {
121 return isMatch(path, directory, false);
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144 public boolean isMatch(String path, boolean directory, boolean pathMatch) {
145 if (path == null)
146 return false;
147 if (path.length() == 0)
148 return false;
149 boolean match = matcher.matches(path, directory, pathMatch);
150 return match;
151 }
152
153
154
155
156
157
158 public boolean getNameOnly() {
159 return !(matcher instanceof PathMatcher);
160 }
161
162
163
164
165
166
167 public boolean dirOnly() {
168 return dirOnly;
169 }
170
171
172
173
174
175
176 public boolean getNegation() {
177 return inverse;
178 }
179
180
181
182
183
184
185 public boolean getResult() {
186 return !inverse;
187 }
188
189
190
191
192
193
194
195
196 public boolean isEmpty() {
197 return matcher == NO_MATCH;
198 }
199
200
201 @Override
202 public String toString() {
203 StringBuilder sb = new StringBuilder();
204 if (inverse)
205 sb.append('!');
206 sb.append(matcher);
207 if (dirOnly)
208 sb.append(PATH_SEPARATOR);
209 return sb.toString();
210
211 }
212
213
214 @Override
215 public int hashCode() {
216 final int prime = 31;
217 int result = 1;
218 result = prime * result + (inverse ? 1231 : 1237);
219 result = prime * result + (dirOnly ? 1231 : 1237);
220 result = prime * result + ((matcher == null) ? 0 : matcher.hashCode());
221 return result;
222 }
223
224
225 @Override
226 public boolean equals(Object obj) {
227 if (this == obj)
228 return true;
229 if (!(obj instanceof FastIgnoreRule))
230 return false;
231
232 FastIgnoreRule other = (FastIgnoreRule) obj;
233 if (inverse != other.inverse)
234 return false;
235 if (dirOnly != other.dirOnly)
236 return false;
237 return matcher.equals(other.matcher);
238 }
239 }