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