View Javadoc
1   package org.codehaus.plexus.util;
2   
3   /*
4    * Copyright The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.File;
20  import java.io.IOException;
21  import java.net.URI;
22  import java.net.URISyntaxException;
23  import java.net.URL;
24  import java.nio.file.Files;
25  import java.nio.file.Paths;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Set;
31  
32  import org.junit.jupiter.api.BeforeEach;
33  import org.junit.jupiter.api.Test;
34  
35  import static org.junit.jupiter.api.Assertions.assertEquals;
36  import static org.junit.jupiter.api.Assertions.assertFalse;
37  import static org.junit.jupiter.api.Assertions.assertTrue;
38  import static org.junit.jupiter.api.Assertions.fail;
39  import static org.junit.jupiter.api.Assumptions.assumeTrue;
40  
41  /**
42   * Base class for testcases doing tests with files.
43   *
44   * @author Dan T. Tran
45   * @version $Id: $Id
46   * @since 3.4.0
47   */
48  public class DirectoryScannerTest extends FileBasedTestCase {
49      private static String testDir = getTestDirectory().getPath();
50  
51      /**
52       * <p>setUp.</p>
53       */
54      @BeforeEach
55      public void setUp() {
56          try {
57              FileUtils.deleteDirectory(testDir);
58          } catch (IOException e) {
59              fail("Could not delete directory " + testDir);
60          }
61      }
62  
63      /**
64       * <p>testCrossPlatformIncludesString.</p>
65       *
66       * @throws java.io.IOException if any.
67       * @throws java.net.URISyntaxException if any.
68       */
69      @Test
70      public void testCrossPlatformIncludesString() throws IOException, URISyntaxException {
71          DirectoryScanner ds = new DirectoryScanner();
72          ds.setBasedir(new File(getTestResourcesDir() + File.separator + "directory-scanner").getCanonicalFile());
73  
74          String fs;
75          if (File.separatorChar == '/') {
76              fs = "\\";
77          } else {
78              fs = "/";
79          }
80  
81          ds.setIncludes(new String[] {"foo" + fs});
82          ds.addDefaultExcludes();
83          ds.scan();
84  
85          String[] files = ds.getIncludedFiles();
86          assertEquals(1, files.length);
87      }
88  
89      /**
90       * <p>testCrossPlatformExcludesString.</p>
91       *
92       * @throws java.io.IOException if any.
93       * @throws java.net.URISyntaxException if any.
94       */
95      @Test
96      public void testCrossPlatformExcludesString() throws IOException, URISyntaxException {
97          DirectoryScanner ds = new DirectoryScanner();
98          ds.setBasedir(new File(getTestResourcesDir() + File.separator + "directory-scanner").getCanonicalFile());
99          ds.setIncludes(new String[] {"**"});
100 
101         String fs;
102         if (File.separatorChar == '/') {
103             fs = "\\";
104         } else {
105             fs = "/";
106         }
107 
108         ds.setExcludes(new String[] {"foo" + fs});
109         ds.addDefaultExcludes();
110         ds.scan();
111 
112         String[] files = ds.getIncludedFiles();
113         assertEquals(0, files.length);
114     }
115 
116     private String getTestResourcesDir() throws URISyntaxException {
117         ClassLoader cloader = Thread.currentThread().getContextClassLoader();
118         URL resource = cloader.getResource("test.txt");
119         if (resource == null) {
120             fail("Cannot locate test-resources directory containing 'test.txt' in the classloader.");
121         }
122 
123         File file = new File(new URI(resource.toExternalForm()).normalize().getPath());
124 
125         return file.getParent();
126     }
127 
128     private void createTestFiles() throws IOException {
129         FileUtils.mkdir(testDir);
130         this.createFile(new File(testDir + "/scanner1.dat"), 0);
131         this.createFile(new File(testDir + "/scanner2.dat"), 0);
132         this.createFile(new File(testDir + "/scanner3.dat"), 0);
133         this.createFile(new File(testDir + "/scanner4.dat"), 0);
134         this.createFile(new File(testDir + "/scanner5.dat"), 0);
135     }
136 
137     /**
138      * Check if 'src/test/resources/symlinks/src/sym*' test files (start with 'sym') exist and are symlinks.<br>
139      * On some OS (like Windows 10), the 'git clone' requires to be executed with admin permissions and the
140      * 'core.symlinks=true' git option.
141      *
142      * @return true If files here and symlinks, false otherwise
143      */
144     private boolean checkTestFilesSymlinks() {
145         File symlinksDirectory = new File("src/test/resources/symlinks/src");
146         try {
147             List<String> symlinks =
148                     FileUtils.getFileAndDirectoryNames(symlinksDirectory, "sym*", null, true, true, true, true);
149             if (symlinks.isEmpty()) {
150                 throw new IOException("Symlinks files/directories are not present");
151             }
152             for (String symLink : symlinks) {
153                 if (!Files.isSymbolicLink(Paths.get(symLink))) {
154                     throw new IOException(String.format("Path is not a symlink: %s", symLink));
155                 }
156             }
157             return true;
158         } catch (IOException e) {
159             System.err.println(String.format(
160                     "The unit test '%s.%s' will be skipped, reason: %s",
161                     this.getClass().getSimpleName(), getTestMethodName(), e.getMessage()));
162             System.out.println(
163                     String.format("This test requires symlinks files in '%s' directory.", symlinksDirectory.getPath()));
164             System.out.println("On some OS (like Windows 10), files are present only if the clone/checkout is done"
165                     + " in administrator mode, and correct (symlinks and not flat file/directory)"
166                     + " if symlinks option are used (for git: git clone -c core.symlinks=true [url])");
167             return false;
168         }
169     }
170 
171     /**
172      * <p>testGeneral.</p>
173      *
174      * @throws java.io.IOException if any.
175      */
176     @Test
177     public void testGeneral() throws IOException {
178         this.createTestFiles();
179 
180         String includes = "scanner1.dat,scanner2.dat,scanner3.dat,scanner4.dat,scanner5.dat";
181         String excludes = "scanner1.dat,scanner2.dat";
182 
183         List<File> fileNames = FileUtils.getFiles(new File(testDir), includes, excludes, false);
184 
185         assertEquals(3, fileNames.size(), "Wrong number of results.");
186         assertTrue(fileNames.contains(new File("scanner3.dat")), "3 not found.");
187         assertTrue(fileNames.contains(new File("scanner4.dat")), "4 not found.");
188         assertTrue(fileNames.contains(new File("scanner5.dat")), "5 not found.");
189     }
190 
191     /**
192      * <p>testIncludesExcludesWithWhiteSpaces.</p>
193      *
194      * @throws java.io.IOException if any.
195      */
196     @Test
197     public void testIncludesExcludesWithWhiteSpaces() throws IOException {
198         this.createTestFiles();
199 
200         String includes = "scanner1.dat,\n  \n,scanner2.dat  \n\r, scanner3.dat\n, \tscanner4.dat,scanner5.dat\n,";
201 
202         String excludes = "scanner1.dat,\n  \n,scanner2.dat  \n\r,,";
203 
204         List<File> fileNames = FileUtils.getFiles(new File(testDir), includes, excludes, false);
205 
206         assertEquals(3, fileNames.size(), "Wrong number of results.");
207         assertTrue(fileNames.contains(new File("scanner3.dat")), "3 not found.");
208         assertTrue(fileNames.contains(new File("scanner4.dat")), "4 not found.");
209         assertTrue(fileNames.contains(new File("scanner5.dat")), "5 not found.");
210     }
211 
212     /**
213      * <p>testFollowSymlinksFalse.</p>
214      */
215     @Test
216     public void testFollowSymlinksFalse() {
217         assumeTrue(checkTestFilesSymlinks());
218 
219         DirectoryScanner ds = new DirectoryScanner();
220         ds.setBasedir(new File("src/test/resources/symlinks/src/"));
221         ds.setFollowSymlinks(false);
222         ds.scan();
223         List<String> included = Arrays.asList(ds.getIncludedFiles());
224         assertAlwaysIncluded(included);
225         assertEquals(9, included.size());
226         List<String> includedDirs = Arrays.asList(ds.getIncludedDirectories());
227         assertTrue(includedDirs.contains("")); // w00t !
228         assertTrue(includedDirs.contains("aRegularDir"));
229         assertTrue(includedDirs.contains("symDir"));
230         assertTrue(includedDirs.contains("symLinkToDirOnTheOutside"));
231         assertTrue(includedDirs.contains("targetDir"));
232         assertEquals(5, includedDirs.size());
233     }
234 
235     private void assertAlwaysIncluded(List<String> included) {
236         assertTrue(included.contains("aRegularDir" + File.separator + "aRegularFile.txt"));
237         assertTrue(included.contains("targetDir" + File.separator + "targetFile.txt"));
238         assertTrue(included.contains("fileR.txt"));
239         assertTrue(included.contains("fileW.txt"));
240         assertTrue(included.contains("fileX.txt"));
241         assertTrue(included.contains("symR"));
242         assertTrue(included.contains("symW"));
243         assertTrue(included.contains("symX"));
244         assertTrue(included.contains("symLinkToFileOnTheOutside"));
245     }
246 
247     /**
248      * <p>testFollowSymlinks.</p>
249      */
250     @Test
251     public void testFollowSymlinks() {
252         assumeTrue(checkTestFilesSymlinks());
253 
254         DirectoryScanner ds = new DirectoryScanner();
255         ds.setBasedir(new File("src/test/resources/symlinks/src/"));
256         ds.setFollowSymlinks(true);
257         ds.scan();
258         List<String> included = Arrays.asList(ds.getIncludedFiles());
259         assertAlwaysIncluded(included);
260         assertTrue(included.contains("symDir" + File.separator + "targetFile.txt"));
261         assertTrue(included.contains("symLinkToDirOnTheOutside" + File.separator + "FileInDirOnTheOutside.txt"));
262         assertEquals(11, included.size());
263 
264         List<String> includedDirs = Arrays.asList(ds.getIncludedDirectories());
265         assertTrue(includedDirs.contains("")); // w00t !
266         assertTrue(includedDirs.contains("aRegularDir"));
267         assertTrue(includedDirs.contains("symDir"));
268         assertTrue(includedDirs.contains("symLinkToDirOnTheOutside"));
269         assertTrue(includedDirs.contains("targetDir"));
270         assertEquals(5, includedDirs.size());
271     }
272 
273     private void createTestDirectories() throws IOException {
274         FileUtils.mkdir(testDir + File.separator + "directoryTest");
275         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "testDir123");
276         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "test_dir_123");
277         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "test-dir-123");
278         this.createFile(
279                 new File(testDir + File.separator + "directoryTest" + File.separator + "testDir123" + File.separator
280                         + "file1.dat"),
281                 0);
282         this.createFile(
283                 new File(testDir + File.separator + "directoryTest" + File.separator + "test_dir_123" + File.separator
284                         + "file1.dat"),
285                 0);
286         this.createFile(
287                 new File(testDir + File.separator + "directoryTest" + File.separator + "test-dir-123" + File.separator
288                         + "file1.dat"),
289                 0);
290     }
291 
292     /**
293      * <p>testDirectoriesWithHyphens.</p>
294      *
295      * @throws java.io.IOException if any.
296      */
297     @Test
298     public void testDirectoriesWithHyphens() throws IOException {
299         this.createTestDirectories();
300 
301         DirectoryScanner ds = new DirectoryScanner();
302         String[] includes = {"**/*.dat"};
303         String[] excludes = {""};
304         ds.setIncludes(includes);
305         ds.setExcludes(excludes);
306         ds.setBasedir(new File(testDir + File.separator + "directoryTest"));
307         ds.setCaseSensitive(true);
308         ds.scan();
309 
310         String[] files = ds.getIncludedFiles();
311         assertEquals(3, files.length, "Wrong number of results.");
312     }
313 
314     /**
315      * <p>testAntExcludesOverrideIncludes.</p>
316      *
317      * @throws java.io.IOException if any.
318      */
319     @Test
320     public void testAntExcludesOverrideIncludes() throws IOException {
321         printTestHeader();
322 
323         File dir = new File(testDir, "regex-dir");
324         dir.mkdirs();
325 
326         String[] excludedPaths = {"target/foo.txt"};
327 
328         createFiles(dir, excludedPaths);
329 
330         String[] includedPaths = {"src/main/resources/project/target/foo.txt"};
331 
332         createFiles(dir, includedPaths);
333 
334         DirectoryScanner ds = new DirectoryScanner();
335 
336         String[] includes = {"**/target/*"};
337         String[] excludes = {"target/*"};
338 
339         // This doesn't work, since excluded patterns refine included ones, meaning they operate on
340         // the list of paths that passed the included patterns, and can override them.
341         // String[] includes = {"**src/**/target/**/*" };
342         // String[] excludes = { "**/target/**/*" };
343 
344         ds.setIncludes(includes);
345         ds.setExcludes(excludes);
346         ds.setBasedir(dir);
347         ds.scan();
348 
349         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
350     }
351 
352     /**
353      * <p>testAntExcludesOverrideIncludesWithExplicitAntPrefix.</p>
354      *
355      * @throws java.io.IOException if any.
356      */
357     @org.junit.jupiter.api.Test
358     public void testAntExcludesOverrideIncludesWithExplicitAntPrefix() throws IOException {
359         printTestHeader();
360 
361         File dir = new File(testDir, "regex-dir");
362         dir.mkdirs();
363 
364         String[] excludedPaths = {"target/foo.txt"};
365 
366         createFiles(dir, excludedPaths);
367 
368         String[] includedPaths = {"src/main/resources/project/target/foo.txt"};
369 
370         createFiles(dir, includedPaths);
371 
372         DirectoryScanner ds = new DirectoryScanner();
373 
374         String[] includes = {SelectorUtils.ANT_HANDLER_PREFIX + "**/target/**/*" + SelectorUtils.PATTERN_HANDLER_SUFFIX
375         };
376         String[] excludes = {SelectorUtils.ANT_HANDLER_PREFIX + "target/**/*" + SelectorUtils.PATTERN_HANDLER_SUFFIX};
377 
378         // This doesn't work, since excluded patterns refine included ones, meaning they operate on
379         // the list of paths that passed the included patterns, and can override them.
380         // String[] includes = {"**src/**/target/**/*" };
381         // String[] excludes = { "**/target/**/*" };
382 
383         ds.setIncludes(includes);
384         ds.setExcludes(excludes);
385         ds.setBasedir(dir);
386         ds.scan();
387 
388         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
389     }
390 
391     /**
392      * <p>testRegexIncludeWithExcludedPrefixDirs.</p>
393      *
394      * @throws java.io.IOException if any.
395      */
396     @org.junit.jupiter.api.Test
397     public void testRegexIncludeWithExcludedPrefixDirs() throws IOException {
398         printTestHeader();
399 
400         File dir = new File(testDir, "regex-dir");
401         dir.mkdirs();
402 
403         String[] excludedPaths = {"src/main/foo.txt"};
404 
405         createFiles(dir, excludedPaths);
406 
407         String[] includedPaths = {"src/main/resources/project/target/foo.txt"};
408 
409         createFiles(dir, includedPaths);
410 
411         String regex = ".+/target.*";
412 
413         DirectoryScanner ds = new DirectoryScanner();
414 
415         String includeExpr = SelectorUtils.REGEX_HANDLER_PREFIX + regex + SelectorUtils.PATTERN_HANDLER_SUFFIX;
416 
417         String[] includes = {includeExpr};
418         ds.setIncludes(includes);
419         ds.setBasedir(dir);
420         ds.scan();
421 
422         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
423     }
424 
425     /**
426      * <p>testRegexExcludeWithNegativeLookahead.</p>
427      *
428      * @throws java.io.IOException if any.
429      */
430     @org.junit.jupiter.api.Test
431     public void testRegexExcludeWithNegativeLookahead() throws IOException {
432         printTestHeader();
433 
434         File dir = new File(testDir, "regex-dir");
435         try {
436             FileUtils.deleteDirectory(dir);
437         } catch (IOException e) {
438         }
439 
440         dir.mkdirs();
441 
442         String[] excludedPaths = {"target/foo.txt"};
443 
444         createFiles(dir, excludedPaths);
445 
446         String[] includedPaths = {"src/main/resources/project/target/foo.txt"};
447 
448         createFiles(dir, includedPaths);
449 
450         String regex = "(?!.*src/).*target.*";
451 
452         DirectoryScanner ds = new DirectoryScanner();
453 
454         String excludeExpr = SelectorUtils.REGEX_HANDLER_PREFIX + regex + SelectorUtils.PATTERN_HANDLER_SUFFIX;
455 
456         String[] excludes = {excludeExpr};
457         ds.setExcludes(excludes);
458         ds.setBasedir(dir);
459         ds.scan();
460 
461         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
462     }
463 
464     /**
465      * <p>testRegexWithSlashInsideCharacterClass.</p>
466      *
467      * @throws java.io.IOException if any.
468      */
469     @Test
470     public void testRegexWithSlashInsideCharacterClass() throws IOException {
471         printTestHeader();
472 
473         File dir = new File(testDir, "regex-dir");
474         try {
475             FileUtils.deleteDirectory(dir);
476         } catch (IOException e) {
477         }
478 
479         dir.mkdirs();
480 
481         String[] excludedPaths = {"target/foo.txt", "target/src/main/target/foo.txt"};
482 
483         createFiles(dir, excludedPaths);
484 
485         String[] includedPaths = {"module/src/main/target/foo.txt"};
486 
487         createFiles(dir, includedPaths);
488 
489         // NOTE: The portion "[^/]" is the interesting part of this pattern.
490         String regex = "(?!((?!target/)[^/]+/)*src/).*target.*";
491 
492         DirectoryScanner ds = new DirectoryScanner();
493 
494         String excludeExpr = SelectorUtils.REGEX_HANDLER_PREFIX + regex + SelectorUtils.PATTERN_HANDLER_SUFFIX;
495 
496         String[] excludes = {excludeExpr};
497         ds.setExcludes(excludes);
498         ds.setBasedir(dir);
499         ds.scan();
500 
501         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
502     }
503 
504     /**
505      * Test that the directory scanning does not enter into not matching directories.
506      *
507      * @see <a href="https://github.com/codehaus-plexus/plexus-utils/issues/63">Issue #63</a>
508      * @throws java.io.IOException if occurs an I/O error.
509      */
510     @Test
511     public void testDoNotScanUnnecesaryDirectories() throws IOException {
512         createTestDirectories();
513 
514         // create additional directories 'anotherDir1', 'anotherDir2' and 'anotherDir3' with a 'file1.dat' file
515         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "testDir123" + File.separator
516                 + "anotherDir1");
517         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "test_dir_123" + File.separator
518                 + "anotherDir2");
519         FileUtils.mkdir(testDir + File.separator + "directoryTest" + File.separator + "test-dir-123" + File.separator
520                 + "anotherDir3");
521 
522         this.createFile(
523                 new File(testDir + File.separator + "directoryTest" + File.separator + "testDir123" + File.separator
524                         + "anotherDir1" + File.separator + "file1.dat"),
525                 0);
526         this.createFile(
527                 new File(testDir + File.separator + "directoryTest" + File.separator + "test_dir_123" + File.separator
528                         + "anotherDir2" + File.separator + "file1.dat"),
529                 0);
530         this.createFile(
531                 new File(testDir + File.separator + "directoryTest" + File.separator + "test-dir-123" + File.separator
532                         + "anotherDir3" + File.separator + "file1.dat"),
533                 0);
534 
535         String[] excludedPaths = {
536             "directoryTest" + File.separator + "testDir123" + File.separator + "anotherDir1" + File.separator
537                     + "file1.dat",
538             "directoryTest" + File.separator + "test_dir_123" + File.separator + "anotherDir2" + File.separator
539                     + "file1.dat",
540             "directoryTest" + File.separator + "test-dir-123" + File.separator + "anotherDir3" + File.separator
541                     + "file1.dat"
542         };
543 
544         String[] includedPaths = {
545             "directoryTest" + File.separator + "testDir123" + File.separator + "file1.dat",
546             "directoryTest" + File.separator + "test_dir_123" + File.separator + "file1.dat",
547             "directoryTest" + File.separator + "test-dir-123" + File.separator + "file1.dat"
548         };
549 
550         final Set<String> scannedDirSet = new HashSet<String>();
551 
552         DirectoryScanner ds = new DirectoryScanner() {
553             @Override
554             protected void scandir(File dir, String vpath, boolean fast) {
555                 scannedDirSet.add(dir.getName());
556                 super.scandir(dir, vpath, fast);
557             }
558         };
559 
560         // one '*' matches only ONE directory level
561         String[] includes = {"directoryTest" + File.separator + "*" + File.separator + "file1.dat"};
562         ds.setIncludes(includes);
563         ds.setBasedir(new File(testDir));
564         ds.scan();
565 
566         assertInclusionsAndExclusions(ds.getIncludedFiles(), excludedPaths, includedPaths);
567 
568         Set<String> expectedScannedDirSet =
569                 new HashSet<String>(Arrays.asList("io", "directoryTest", "testDir123", "test_dir_123", "test-dir-123"));
570 
571         assertEquals(expectedScannedDirSet, scannedDirSet);
572     }
573 
574     /**
575      * <p>testIsSymbolicLink.</p>
576      *
577      * @throws java.io.IOException if any.
578      */
579     @Test
580     public void testIsSymbolicLink() throws IOException {
581         assumeTrue(checkTestFilesSymlinks());
582 
583         final File directory = new File("src/test/resources/symlinks/src");
584         DirectoryScanner ds = new DirectoryScanner();
585         assertTrue(ds.isSymbolicLink(directory, "symR"));
586         assertTrue(ds.isSymbolicLink(directory, "symDir"));
587         assertFalse(ds.isSymbolicLink(directory, "fileR.txt"));
588         assertFalse(ds.isSymbolicLink(directory, "aRegularDir"));
589     }
590 
591     /**
592      * <p>testIsParentSymbolicLink.</p>
593      *
594      * @throws java.io.IOException if any.
595      */
596     @Test
597     public void testIsParentSymbolicLink() throws IOException {
598         assumeTrue(checkTestFilesSymlinks());
599 
600         final File directory = new File("src/test/resources/symlinks/src");
601         DirectoryScanner ds = new DirectoryScanner();
602         assertFalse(ds.isParentSymbolicLink(directory, "symR"));
603         assertFalse(ds.isParentSymbolicLink(directory, "symDir"));
604         assertFalse(ds.isParentSymbolicLink(directory, "fileR.txt"));
605         assertFalse(ds.isParentSymbolicLink(directory, "aRegularDir"));
606         assertFalse(ds.isParentSymbolicLink(new File(directory, "aRegularDir"), "aRegulatFile.txt"));
607         assertTrue(ds.isParentSymbolicLink(new File(directory, "symDir"), "targetFile.txt"));
608         assertTrue(
609                 ds.isParentSymbolicLink(new File(directory, "symLinkToDirOnTheOutside"), "FileInDirOnTheOutside.txt"));
610     }
611 
612     private void printTestHeader() {
613         StackTraceElement ste = new Throwable().getStackTrace()[1];
614         System.out.println("Test: " + ste.getMethodName());
615     }
616 
617     private void assertInclusionsAndExclusions(String[] files, String[] excludedPaths, String... includedPaths) {
618         Arrays.sort(files);
619 
620         System.out.println("Included files: ");
621         for (String file : files) {
622             System.out.println(file);
623         }
624 
625         List<String> failedToExclude = new ArrayList<String>();
626         for (String excludedPath : excludedPaths) {
627             String alt = excludedPath.replace('/', '\\');
628             System.out.println("Searching for exclusion as: " + excludedPath + "\nor: " + alt);
629             if (Arrays.binarySearch(files, excludedPath) > -1 || Arrays.binarySearch(files, alt) > -1) {
630                 failedToExclude.add(excludedPath);
631             }
632         }
633 
634         List<String> failedToInclude = new ArrayList<String>();
635         for (String includedPath : includedPaths) {
636             String alt = includedPath.replace('/', '\\');
637             System.out.println("Searching for inclusion as: " + includedPath + "\nor: " + alt);
638             if (Arrays.binarySearch(files, includedPath) < 0 && Arrays.binarySearch(files, alt) < 0) {
639                 failedToInclude.add(includedPath);
640             }
641         }
642 
643         StringBuilder buffer = new StringBuilder();
644         if (!failedToExclude.isEmpty()) {
645             buffer.append("Should NOT have included:\n").append(StringUtils.join(failedToExclude.iterator(), "\n\t- "));
646         }
647 
648         if (!failedToInclude.isEmpty()) {
649             if (buffer.length() > 0) {
650                 buffer.append("\n\n");
651             }
652 
653             buffer.append("Should have included:\n").append(StringUtils.join(failedToInclude.iterator(), "\n\t- "));
654         }
655 
656         if (buffer.length() > 0) {
657             fail(buffer.toString());
658         }
659     }
660 
661     private void createFiles(File dir, String... paths) throws IOException {
662         for (String path1 : paths) {
663             String path = path1.replace('/', File.separatorChar).replace('\\', File.separatorChar);
664             File file = new File(dir, path);
665 
666             if (path.endsWith(File.separator)) {
667                 file.mkdirs();
668             } else {
669                 if (file.getParentFile() != null) {
670                     file.getParentFile().mkdirs();
671                 }
672 
673                 createFile(file, 0);
674             }
675         }
676     }
677 }