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 }