1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codehaus.mojo.wagon.shared;
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import static org.codehaus.plexus.util.StringUtils.isBlank;
34
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.Iterator;
38 import java.util.List;
39
40 import org.apache.maven.plugin.logging.Log;
41 import org.apache.maven.wagon.Wagon;
42 import org.apache.maven.wagon.WagonException;
43 import org.codehaus.plexus.util.StringUtils;
44 import org.kuali.common.util.inform.Inform;
45 import org.kuali.common.util.inform.PercentCompleteInformer;
46
47 public class WagonDirectoryScanner {
48
49 private final static String[] NOT_DIRECTORIES = new String[] { ".jar", ".zip", ".md5", ".sha1", ".pom", ".xml", ".war" };
50
51
52
53
54
55
56 public static final String[] DEFAULTEXCLUDES = org.codehaus.plexus.util.DirectoryScanner.DEFAULTEXCLUDES;
57
58
59
60
61 private Wagon wagon;
62
63
64
65
66 private String directory;
67
68
69
70
71 private PercentCompleteInformer informer = new PercentCompleteInformer(100);
72
73
74 private String[] includes;
75
76
77 private String[] excludes;
78
79
80
81
82 private boolean isCaseSensitive = true;
83
84
85
86
87 private List<String> filesIncluded = new ArrayList<String>();
88
89 private Log logger;
90
91
92
93
94
95
96
97
98
99
100
101 public void setIncludes(String[] includes) {
102 if (includes == null) {
103 this.includes = null;
104 } else {
105 this.includes = new String[includes.length];
106 for (int i = 0; i < includes.length; i++) {
107 String pattern = includes[i].trim();
108
109 if (pattern.endsWith("/")) {
110 pattern += "**";
111 }
112 this.includes[i] = pattern;
113 }
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126 public void setExcludes(String[] excludes) {
127 if (excludes == null) {
128 this.excludes = null;
129 } else {
130 this.excludes = new String[excludes.length];
131 for (int i = 0; i < excludes.length; i++) {
132 String pattern = excludes[i].trim();
133
134 if (pattern.endsWith("/")) {
135 pattern += "**";
136 }
137 this.excludes[i] = pattern;
138 }
139 }
140 }
141
142
143
144
145
146
147
148
149 private boolean isIncluded(String name) {
150 logger.debug("includes.length=" + includes.length);
151 for (int i = 0; i < includes.length; i++) {
152 logger.debug("includes[" + i + "]=" + includes[i]);
153 if (matchPath(includes[i], name, isCaseSensitive)) {
154 return true;
155 }
156 }
157 return false;
158 }
159
160
161
162
163
164
165
166
167 protected boolean isExcluded(String name) {
168 for (int i = 0; i < excludes.length; i++) {
169 if (matchPath(excludes[i], name, isCaseSensitive)) {
170 return true;
171 }
172 }
173 return false;
174 }
175
176
177
178
179
180
181
182
183 protected boolean couldHoldIncluded(String name) {
184 for (int i = 0; i < includes.length; i++) {
185 if (matchPatternStart(includes[i], name, isCaseSensitive)) {
186 return true;
187 }
188 }
189 return false;
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 protected static boolean matchPatternStart(String pattern, String str, boolean isCaseSensitive) {
208 return SelectorUtils.matchPatternStart(pattern, str, isCaseSensitive);
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223 private static boolean matchPath(String pattern, String str, boolean isCaseSensitive) {
224 return SelectorUtils.matchPath(pattern, str, isCaseSensitive);
225 }
226
227 public void scan() throws WagonException {
228 if (wagon == null) {
229 throw new IllegalStateException("No wagon set");
230 }
231
232 if (StringUtils.isBlank(directory)) {
233 directory = "";
234 }
235
236
237
238 if (includes == null) {
239
240 includes = new String[1];
241 includes[0] = "**";
242 }
243
244 if (excludes == null) {
245 excludes = new String[0];
246 }
247
248 filesIncluded = new ArrayList<String>();
249
250 scandir(directory);
251
252 Collections.sort(filesIncluded);
253
254 }
255
256
257
258
259 public void addDefaultExcludes() {
260 int excludesLength = excludes == null ? 0 : excludes.length;
261 String[] newExcludes;
262 newExcludes = new String[excludesLength + DEFAULTEXCLUDES.length];
263 if (excludesLength > 0) {
264 System.arraycopy(excludes, 0, newExcludes, 0, excludesLength);
265 }
266 for (int i = 0; i < DEFAULTEXCLUDES.length; i++) {
267 newExcludes[i + excludesLength] = DEFAULTEXCLUDES[i];
268 }
269 excludes = newExcludes;
270 }
271
272
273
274
275
276
277
278
279
280 private boolean isRidiculousFile(String fileName) {
281 return fileName.endsWith(".") || fileName.contains("*") || fileName.startsWith("?") || fileName.startsWith("#");
282 }
283
284
285
286
287
288
289
290
291
292 protected void scandir(String dir) throws WagonException {
293 if (this.informer != null) {
294 synchronized (informer) {
295 informer.incrementProgress();
296 if (informer.getProgress() % informer.getTotal() == 0) {
297 Inform inform = informer.getInform();
298 String msg = String.format(" - scanned %s dirs%s%s", informer.getProgress(), inform.getCompleteToken(), inform.getStartToken());
299 inform.getPrintStream().print(msg);
300 }
301 }
302 }
303 if (isBlank(dir)) {
304 logger.debug("Scanning '" + dir + "'");
305 } else {
306 logger.debug("Scanning " + dir);
307 }
308 List<?> files = wagon.getFileList(dir);
309
310 for (Iterator<?> itr = files.iterator(); itr.hasNext();) {
311 String fileName = (String) itr.next();
312 if (isRidiculousFile(fileName)) {
313 continue;
314 }
315
316 boolean directory = isDirectory(fileName);
317 boolean included = isIncluded(fileName);
318 boolean excluded = isExcluded(fileName);
319 boolean chi = directory && couldHoldIncluded(fileName);
320 boolean include = included && !excluded || chi && !excluded;
321
322 if (!include) {
323 logger.debug("Skipping " + fileName);
324 logger.debug("fileName=" + fileName + " included=" + included + " excluded=" + excluded + " chi=" + chi);
325 continue;
326 }
327
328 if (directory) {
329 scandir(fileName);
330 } else {
331 filesIncluded.add(fileName);
332 }
333 }
334 }
335
336 private boolean isDirectory(String existingRemotePath) throws WagonException {
337 for (int x = 0; x < NOT_DIRECTORIES.length; x++) {
338 if (existingRemotePath.endsWith(NOT_DIRECTORIES[x])) {
339 return false;
340 }
341 }
342 return existingRemotePath.endsWith("/");
343 }
344
345 public List<String> getFilesIncluded() {
346 return filesIncluded;
347 }
348
349 public void setWagon(Wagon wagon) {
350 this.wagon = wagon;
351 }
352
353 public void setCaseSensitive(boolean isCaseSensitive) {
354 this.isCaseSensitive = isCaseSensitive;
355 }
356
357 public void setDirectory(String basePath) {
358 this.directory = basePath;
359 }
360
361 public Log getLogger() {
362 return logger;
363 }
364
365 public void setLogger(Log logger) {
366 this.logger = logger;
367 }
368
369 public PercentCompleteInformer getInformer() {
370 return informer;
371 }
372
373 public void setInformer(PercentCompleteInformer informer) {
374 this.informer = informer;
375 }
376
377 }