1 18 19 package org.apache.tools.ant; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Iterator ; 28 import java.util.Map ; 29 import java.util.Set ; 30 import java.util.Vector ; 31 32 import org.apache.tools.ant.taskdefs.condition.Os; 33 import org.apache.tools.ant.types.Resource; 34 import org.apache.tools.ant.types.ResourceFactory; 35 import org.apache.tools.ant.types.resources.FileResource; 36 import org.apache.tools.ant.types.selectors.FileSelector; 37 import org.apache.tools.ant.types.selectors.SelectorScanner; 38 import org.apache.tools.ant.types.selectors.SelectorUtils; 39 import org.apache.tools.ant.util.FileUtils; 40 41 124 public class DirectoryScanner 125 implements FileScanner, SelectorScanner, ResourceFactory { 126 127 128 private static final boolean ON_VMS = Os.isFamily("openvms"); 129 130 142 protected static final String [] DEFAULTEXCLUDES = { 143 "**/*~", 145 "**/#*#", 146 "**/.#*", 147 "**/%*%", 148 "**/._*", 149 150 "**/CVS", 152 "**/CVS/**", 153 "**/.cvsignore", 154 155 "**/SCCS", 157 "**/SCCS/**", 158 159 "**/vssver.scc", 161 162 "**/.svn", 164 "**/.svn/**", 165 166 "**/.DS_Store" 168 }; 169 170 171 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 172 173 174 private static final boolean[] CS_SCAN_ONLY = new boolean[] {true}; 175 176 177 private static final boolean[] CS_THEN_NON_CS = new boolean[] {true, false}; 178 179 184 private static Vector defaultExcludes = new Vector (); 185 static { 186 resetDefaultExcludes(); 187 } 188 189 191 192 protected File basedir; 193 194 195 protected String [] includes; 196 197 198 protected String [] excludes; 199 200 201 protected FileSelector[] selectors = null; 202 203 207 protected Vector filesIncluded; 208 209 210 protected Vector filesNotIncluded; 211 212 216 protected Vector filesExcluded; 217 218 222 protected Vector dirsIncluded; 223 224 225 protected Vector dirsNotIncluded; 226 227 231 protected Vector dirsExcluded; 232 233 237 protected Vector filesDeselected; 238 239 243 protected Vector dirsDeselected; 244 245 246 protected boolean haveSlowResults = false; 247 248 252 protected boolean isCaseSensitive = true; 253 254 259 private boolean followSymlinks = true; 260 261 262 protected boolean everythingIncluded = true; 263 264 266 271 private Map fileListMap = new HashMap (); 272 273 278 private Set scannedDirs = new HashSet (); 279 280 293 private Set includeNonPatterns = new HashSet (); 294 295 308 private Set excludeNonPatterns = new HashSet (); 309 310 319 private String [] includePatterns; 320 321 330 private String [] excludePatterns; 331 332 338 private boolean areNonPatternSetsReady = false; 339 340 345 private boolean scanning = false; 346 347 352 private Object scanLock = new Object (); 353 354 359 private boolean slowScanning = false; 360 361 366 private Object slowScanLock = new Object (); 367 368 373 private IllegalStateException illegal = null; 374 375 378 public DirectoryScanner() { 379 } 380 381 397 protected static boolean matchPatternStart(String pattern, String str) { 398 return SelectorUtils.matchPatternStart(pattern, str); 399 } 400 401 419 protected static boolean matchPatternStart(String pattern, String str, 420 boolean isCaseSensitive) { 421 return SelectorUtils.matchPatternStart(pattern, str, isCaseSensitive); 422 } 423 424 435 protected static boolean matchPath(String pattern, String str) { 436 return SelectorUtils.matchPath(pattern, str); 437 } 438 439 452 protected static boolean matchPath(String pattern, String str, 453 boolean isCaseSensitive) { 454 return SelectorUtils.matchPath(pattern, str, isCaseSensitive); 455 } 456 457 471 public static boolean match(String pattern, String str) { 472 return SelectorUtils.match(pattern, str); 473 } 474 475 492 protected static boolean match(String pattern, String str, 493 boolean isCaseSensitive) { 494 return SelectorUtils.match(pattern, str, isCaseSensitive); 495 } 496 497 498 507 public static String [] getDefaultExcludes() { 508 return (String []) defaultExcludes.toArray(new String [defaultExcludes 509 .size()]); 510 } 511 512 522 public static boolean addDefaultExclude(String s) { 523 if (defaultExcludes.indexOf(s) == -1) { 524 defaultExcludes.add(s); 525 return true; 526 } 527 return false; 528 } 529 530 541 public static boolean removeDefaultExclude(String s) { 542 return defaultExcludes.remove(s); 543 } 544 545 550 public static void resetDefaultExcludes() { 551 defaultExcludes = new Vector (); 552 for (int i = 0; i < DEFAULTEXCLUDES.length; i++) { 553 defaultExcludes.add(DEFAULTEXCLUDES[i]); 554 } 555 } 556 557 565 public void setBasedir(String basedir) { 566 setBasedir(basedir == null ? (File ) null 567 : new File (basedir.replace('/', File.separatorChar).replace( 568 '\\', File.separatorChar))); 569 } 570 571 577 public synchronized void setBasedir(File basedir) { 578 this.basedir = basedir; 579 } 580 581 587 public synchronized File getBasedir() { 588 return basedir; 589 } 590 591 597 public synchronized boolean isCaseSensitive() { 598 return isCaseSensitive; 599 } 600 601 608 public synchronized void setCaseSensitive(boolean isCaseSensitive) { 609 this.isCaseSensitive = isCaseSensitive; 610 } 611 612 619 public synchronized boolean isFollowSymlinks() { 620 return followSymlinks; 621 } 622 623 628 public synchronized void setFollowSymlinks(boolean followSymlinks) { 629 this.followSymlinks = followSymlinks; 630 } 631 632 645 public synchronized void setIncludes(String [] includes) { 646 if (includes == null) { 647 this.includes = null; 648 } else { 649 this.includes = new String [includes.length]; 650 for (int i = 0; i < includes.length; i++) { 651 this.includes[i] = normalizePattern(includes[i]); 652 } 653 } 654 } 655 656 668 public synchronized void setExcludes(String [] excludes) { 669 if (excludes == null) { 670 this.excludes = null; 671 } else { 672 this.excludes = new String [excludes.length]; 673 for (int i = 0; i < excludes.length; i++) { 674 this.excludes[i] = normalizePattern(excludes[i]); 675 } 676 } 677 } 678 679 692 public synchronized void addExcludes(String [] excludes) { 693 if (excludes != null && excludes.length > 0) { 694 if (this.excludes != null && this.excludes.length > 0) { 695 String [] tmp = new String [excludes.length 696 + this.excludes.length]; 697 System.arraycopy(this.excludes, 0, tmp, 0, 698 this.excludes.length); 699 for (int i = 0; i < excludes.length; i++) { 700 tmp[this.excludes.length + i] = 701 normalizePattern(excludes[i]); 702 } 703 this.excludes = tmp; 704 } else { 705 setExcludes(excludes); 706 } 707 } 708 } 709 710 719 private static String normalizePattern(String p) { 720 String pattern = p.replace('/', File.separatorChar) 721 .replace('\\', File.separatorChar); 722 if (pattern.endsWith(File.separator)) { 723 pattern += "**"; 724 } 725 return pattern; 726 } 727 728 733 public synchronized void setSelectors(FileSelector[] selectors) { 734 this.selectors = selectors; 735 } 736 737 744 public synchronized boolean isEverythingIncluded() { 745 return everythingIncluded; 746 } 747 748 758 public void scan() throws IllegalStateException { 759 synchronized (scanLock) { 760 if (scanning) { 761 while (scanning) { 762 try { 763 scanLock.wait(); 764 } catch (InterruptedException e) { 765 continue; 766 } 767 } 768 if (illegal != null) { 769 throw illegal; 770 } 771 return; 772 } 773 scanning = true; 774 } 775 try { 776 synchronized (this) { 777 illegal = null; 778 clearResults(); 779 780 boolean nullIncludes = (includes == null); 782 includes = nullIncludes ? new String [] {"**"} : includes; 783 boolean nullExcludes = (excludes == null); 784 excludes = nullExcludes ? new String [0] : excludes; 785 786 if (basedir == null) { 787 if (nullIncludes) { 789 return; 790 } 791 } else { 792 if (!basedir.exists()) { 793 illegal = new IllegalStateException ("basedir " + basedir 794 + " does not exist"); 795 } 796 if (!basedir.isDirectory()) { 797 illegal = new IllegalStateException ("basedir " + basedir 798 + " is not a directory"); 799 } 800 if (illegal != null) { 801 throw illegal; 802 } 803 } 804 if (isIncluded("")) { 805 if (!isExcluded("")) { 806 if (isSelected("", basedir)) { 807 dirsIncluded.addElement(""); 808 } else { 809 dirsDeselected.addElement(""); 810 } 811 } else { 812 dirsExcluded.addElement(""); 813 } 814 } else { 815 dirsNotIncluded.addElement(""); 816 } 817 checkIncludePatterns(); 818 clearCaches(); 819 includes = nullIncludes ? null : includes; 820 excludes = nullExcludes ? null : excludes; 821 } 822 } finally { 823 synchronized (scanLock) { 824 scanning = false; 825 scanLock.notifyAll(); 826 } 827 } 828 } 829 830 835 private void checkIncludePatterns() { 836 Map newroots = new HashMap (); 837 for (int i = 0; i < includes.length; i++) { 840 if (FileUtils.isAbsolutePath(includes[i])) { 841 if (basedir != null 843 && !SelectorUtils.matchPatternStart(includes[i], 844 basedir.getAbsolutePath(), isCaseSensitive())) { 845 continue; 846 } 847 } else if (basedir == null) { 848 continue; 850 } 851 newroots.put(SelectorUtils.rtrimWildcardTokens( 852 includes[i]), includes[i]); 853 } 854 if (newroots.containsKey("") && basedir != null) { 855 scandir(basedir, "", true); 857 } else { 858 Iterator it = newroots.entrySet().iterator(); 861 862 File canonBase = null; 863 if (basedir != null) { 864 try { 865 canonBase = basedir.getCanonicalFile(); 866 } catch (IOException ex) { 867 throw new BuildException(ex); 868 } 869 } 870 while (it.hasNext()) { 871 Map.Entry entry = (Map.Entry ) it.next(); 872 String currentelement = (String ) entry.getKey(); 873 if (basedir == null && !FileUtils.isAbsolutePath(currentelement)) { 874 continue; 875 } 876 String originalpattern = (String ) entry.getValue(); 877 File myfile = new File (basedir, currentelement); 878 879 if (myfile.exists()) { 880 try { 884 String path = (basedir == null) 885 ? myfile.getCanonicalPath() 886 : FILE_UTILS.removeLeadingPath(canonBase, 887 myfile.getCanonicalFile()); 888 if (!path.equals(currentelement) || ON_VMS) { 889 myfile = findFile(basedir, currentelement, true); 890 if (myfile != null && basedir != null) { 891 currentelement = FILE_UTILS.removeLeadingPath( 892 basedir, myfile); 893 } 894 } 895 } catch (IOException ex) { 896 throw new BuildException(ex); 897 } 898 } 899 if ((myfile == null || !myfile.exists()) && !isCaseSensitive()) { 900 File f = findFile(basedir, currentelement, false); 901 if (f != null && f.exists()) { 902 currentelement = (basedir == null) 905 ? f.getAbsolutePath() 906 : FILE_UTILS.removeLeadingPath(basedir, f); 907 myfile = f; 908 } 909 } 910 if (myfile != null && myfile.exists()) { 911 if (!followSymlinks 912 && isSymlink(basedir, currentelement)) { 913 continue; 914 } 915 if (myfile.isDirectory()) { 916 if (isIncluded(currentelement) 917 && currentelement.length() > 0) { 918 accountForIncludedDir(currentelement, myfile, true); 919 } else { 920 if (currentelement.length() > 0) { 921 if (currentelement.charAt(currentelement 922 .length() - 1) 923 != File.separatorChar) { 924 currentelement = 925 currentelement + File.separatorChar; 926 } 927 } 928 scandir(myfile, currentelement, true); 929 } 930 } else { 931 boolean included = isCaseSensitive() 932 ? originalpattern.equals(currentelement) 933 : originalpattern.equalsIgnoreCase(currentelement); 934 if (included) { 935 accountForIncludedFile(currentelement, myfile); 936 } 937 } 938 } 939 } 940 } 941 } 942 943 946 protected synchronized void clearResults() { 947 filesIncluded = new Vector (); 948 filesNotIncluded = new Vector (); 949 filesExcluded = new Vector (); 950 filesDeselected = new Vector (); 951 dirsIncluded = new Vector (); 952 dirsNotIncluded = new Vector (); 953 dirsExcluded = new Vector (); 954 dirsDeselected = new Vector (); 955 everythingIncluded = (basedir != null); 956 scannedDirs.clear(); 957 } 958 959 967 protected void slowScan() { 968 synchronized (slowScanLock) { 969 if (haveSlowResults) { 970 return; 971 } 972 if (slowScanning) { 973 while (slowScanning) { 974 try { 975 slowScanLock.wait(); 976 } catch (InterruptedException e) { 977 } 979 } 980 return; 981 } 982 slowScanning = true; 983 } 984 try { 985 synchronized (this) { 986 987 boolean nullIncludes = (includes == null); 989 includes = nullIncludes ? new String [] {"**"} : includes; 990 boolean nullExcludes = (excludes == null); 991 excludes = nullExcludes ? new String [0] : excludes; 992 993 String [] excl = new String [dirsExcluded.size()]; 994 dirsExcluded.copyInto(excl); 995 996 String [] notIncl = new String [dirsNotIncluded.size()]; 997 dirsNotIncluded.copyInto(notIncl); 998 999 processSlowScan(excl); 1000 processSlowScan(notIncl); 1001 clearCaches(); 1002 includes = nullIncludes ? null : includes; 1003 excludes = nullExcludes ? null : excludes; 1004 } 1005 } finally { 1006 synchronized (slowScanLock) { 1007 haveSlowResults = true; 1008 slowScanning = false; 1009 slowScanLock.notifyAll(); 1010 } 1011 } 1012 } 1013 1014 private void processSlowScan(String [] arr) { 1015 for (int i = 0; i < arr.length; i++) { 1016 if (!couldHoldIncluded(arr[i])) { 1017 scandir(new File (basedir, arr[i]), 1018 arr[i] + File.separator, false); 1019 } 1020 } 1021 } 1022 1023 1043 protected void scandir(File dir, String vpath, boolean fast) { 1044 if (dir == null) { 1045 throw new BuildException("dir must not be null."); 1046 } else if (!dir.exists()) { 1047 throw new BuildException(dir + " doesn't exist."); 1048 } else if (!dir.isDirectory()) { 1049 throw new BuildException(dir + " is not a directory."); 1050 } 1051 if (fast && hasBeenScanned(vpath)) { 1053 return; 1054 } 1055 String [] newfiles = dir.list(); 1056 1057 if (newfiles == null) { 1058 1065 throw new BuildException("IO error scanning directory '" 1066 + dir.getAbsolutePath() + "'"); 1067 } 1068 if (!followSymlinks) { 1069 Vector noLinks = new Vector (); 1070 for (int i = 0; i < newfiles.length; i++) { 1071 try { 1072 if (FILE_UTILS.isSymbolicLink(dir, newfiles[i])) { 1073 String name = vpath + newfiles[i]; 1074 File file = new File (dir, newfiles[i]); 1075 (file.isDirectory() 1076 ? dirsExcluded : filesExcluded).addElement(name); 1077 } else { 1078 noLinks.addElement(newfiles[i]); 1079 } 1080 } catch (IOException ioe) { 1081 String msg = "IOException caught while checking " 1082 + "for links, couldn't get canonical path!"; 1083 System.err.println(msg); 1085 noLinks.addElement(newfiles[i]); 1086 } 1087 } 1088 newfiles = (String []) (noLinks.toArray(new String [noLinks.size()])); 1089 } 1090 for (int i = 0; i < newfiles.length; i++) { 1091 String name = vpath + newfiles[i]; 1092 File file = new File (dir, newfiles[i]); 1093 if (file.isDirectory()) { 1094 if (isIncluded(name)) { 1095 accountForIncludedDir(name, file, fast); 1096 } else { 1097 everythingIncluded = false; 1098 dirsNotIncluded.addElement(name); 1099 if (fast && couldHoldIncluded(name)) { 1100 scandir(file, name + File.separator, fast); 1101 } 1102 } 1103 if (!fast) { 1104 scandir(file, name + File.separator, fast); 1105 } 1106 } else if (file.isFile()) { 1107 if (isIncluded(name)) { 1108 accountForIncludedFile(name, file); 1109 } else { 1110 everythingIncluded = false; 1111 filesNotIncluded.addElement(name); 1112 } 1113 } 1114 } 1115 } 1116 1117 1122 private void accountForIncludedFile(String name, File file) { 1123 processIncluded(name, file, filesIncluded, filesExcluded, filesDeselected); 1124 } 1125 1126 1133 private void accountForIncludedDir(String name, File file, boolean fast) { 1134 processIncluded(name, file, dirsIncluded, dirsExcluded, dirsDeselected); 1135 if (fast && couldHoldIncluded(name) && !contentsExcluded(name)) { 1136 scandir(file, name + File.separator, fast); 1137 } 1138 } 1139 1140 private void processIncluded(String name, File file, Vector inc, Vector exc, Vector des) { 1141 1142 if (inc.contains(name) || exc.contains(name) || des.contains(name)) { return; } 1143 1144 boolean included = false; 1145 if (isExcluded(name)) { 1146 exc.add(name); 1147 } else if (isSelected(name, file)) { 1148 included = true; 1149 inc.add(name); 1150 } else { 1151 des.add(name); 1152 } 1153 everythingIncluded &= included; 1154 } 1155 1156 1164 protected boolean isIncluded(String name) { 1165 ensureNonPatternSetsReady(); 1166 1167 if (isCaseSensitive() 1168 ? includeNonPatterns.contains(name) 1169 : includeNonPatterns.contains(name.toUpperCase())) { 1170 return true; 1171 } 1172 for (int i = 0; i < includePatterns.length; i++) { 1173 if (matchPath(includePatterns[i], name, isCaseSensitive())) { 1174 return true; 1175 } 1176 } 1177 return false; 1178 } 1179 1180 1188 protected boolean couldHoldIncluded(String name) { 1189 for (int i = 0; i < includes.length; i++) { 1190 if (matchPatternStart(includes[i], name, isCaseSensitive()) 1191 && isMorePowerfulThanExcludes(name, includes[i]) 1192 && isDeeper(includes[i], name)) { 1193 return true; 1194 } 1195 } 1196 return false; 1197 } 1198 1199 1207 private boolean isDeeper(String pattern, String name) { 1208 Vector p = SelectorUtils.tokenizePath(pattern); 1209 Vector n = SelectorUtils.tokenizePath(name); 1210 return p.contains("**") || p.size() > n.size(); 1211 } 1212 1213 1229 private boolean isMorePowerfulThanExcludes(String name, String includepattern) { 1230 String soughtexclude = name + File.separator + "**"; 1231 for (int counter = 0; counter < excludes.length; counter++) { 1232 if (excludes[counter].equals(soughtexclude)) { 1233 return false; 1234 } 1235 } 1236 return true; 1237 } 1238 1239 1244 private boolean contentsExcluded(String name) { 1245 name = (name.endsWith(File.separator)) ? name : name + File.separator; 1246 for (int i = 0; i < excludes.length; i++) { 1247 String e = excludes[i]; 1248 if (e.endsWith("**") && SelectorUtils.matchPath( 1249 e.substring(0, e.length() - 2), name, isCaseSensitive())) { 1250 return true; 1251 } 1252 } 1253 return false; 1254 } 1255 1256 1264 protected boolean isExcluded(String name) { 1265 ensureNonPatternSetsReady(); 1266 1267 if (isCaseSensitive() 1268 ? excludeNonPatterns.contains(name) 1269 : excludeNonPatterns.contains(name.toUpperCase())) { 1270 return true; 1271 } 1272 for (int i = 0; i < excludePatterns.length; i++) { 1273 if (matchPath(excludePatterns[i], name, isCaseSensitive())) { 1274 return true; 1275 } 1276 } 1277 return false; 1278 } 1279 1280 1288 protected boolean isSelected(String name, File file) { 1289 if (selectors != null) { 1290 for (int i = 0; i < selectors.length; i++) { 1291 if (!selectors[i].isSelected(basedir, name, file)) { 1292 return false; 1293 } 1294 } 1295 } 1296 return true; 1297 } 1298 1299 1307 public synchronized String [] getIncludedFiles() { 1308 if (filesIncluded == null) { 1309 throw new IllegalStateException ("Must call scan() first"); 1310 } 1311 String [] files = new String [filesIncluded.size()]; 1312 filesIncluded.copyInto(files); 1313 Arrays.sort(files); 1314 return files; 1315 } 1316 1317 1322 public synchronized int getIncludedFilesCount() { 1323 if (filesIncluded == null) { 1324 throw new IllegalStateException ("Must call scan() first"); 1325 } 1326 return filesIncluded.size(); 1327 } 1328 1329 1339 public synchronized String [] getNotIncludedFiles() { 1340 slowScan(); 1341 String [] files = new String [filesNotIncluded.size()]; 1342 filesNotIncluded.copyInto(files); 1343 return files; 1344 } 1345 1346 1357 public synchronized String [] getExcludedFiles() { 1358 slowScan(); 1359 String [] files = new String [filesExcluded.size()]; 1360 filesExcluded.copyInto(files); 1361 return files; 1362 } 1363 1364 1375 public synchronized String [] getDeselectedFiles() { 1376 slowScan(); 1377 String [] files = new String [filesDeselected.size()]; 1378 filesDeselected.copyInto(files); 1379 return files; 1380 } 1381 1382 1390 public synchronized String [] getIncludedDirectories() { 1391 if (dirsIncluded == null) { 1392 throw new IllegalStateException ("Must call scan() first"); 1393 } 1394 String [] directories = new String [dirsIncluded.size()]; 1395 dirsIncluded.copyInto(directories); 1396 Arrays.sort(directories); 1397 return directories; 1398 } 1399 1400 1405 public synchronized int getIncludedDirsCount() { 1406 if (dirsIncluded == null) { 1407 throw new IllegalStateException ("Must call scan() first"); 1408 } 1409 return dirsIncluded.size(); 1410 } 1411 1412 1422 public synchronized String [] getNotIncludedDirectories() { 1423 slowScan(); 1424 String [] directories = new String [dirsNotIncluded.size()]; 1425 dirsNotIncluded.copyInto(directories); 1426 return directories; 1427 } 1428 1429 1440 public synchronized String [] getExcludedDirectories() { 1441 slowScan(); 1442 String [] directories = new String [dirsExcluded.size()]; 1443 dirsExcluded.copyInto(directories); 1444 return directories; 1445 } 1446 1447 1458 public synchronized String [] getDeselectedDirectories() { 1459 slowScan(); 1460 String [] directories = new String [dirsDeselected.size()]; 1461 dirsDeselected.copyInto(directories); 1462 return directories; 1463 } 1464 1465 1468 public synchronized void addDefaultExcludes() { 1469 int excludesLength = excludes == null ? 0 : excludes.length; 1470 String [] newExcludes; 1471 newExcludes = new String [excludesLength + defaultExcludes.size()]; 1472 if (excludesLength > 0) { 1473 System.arraycopy(excludes, 0, newExcludes, 0, excludesLength); 1474 } 1475 String [] defaultExcludesTemp = getDefaultExcludes(); 1476 for (int i = 0; i < defaultExcludesTemp.length; i++) { 1477 newExcludes[i + excludesLength] = 1478 defaultExcludesTemp[i].replace('/', File.separatorChar) 1479 .replace('\\', File.separatorChar); 1480 } 1481 excludes = newExcludes; 1482 } 1483 1484 1491 public synchronized Resource getResource(String name) { 1492 return new FileResource(basedir, name); 1493 } 1494 1495 1502 private String [] list(File file) { 1503 String [] files = (String []) fileListMap.get(file); 1504 if (files == null) { 1505 files = file.list(); 1506 if (files != null) { 1507 fileListMap.put(file, files); 1508 } 1509 } 1510 return files; 1511 } 1512 1513 1524 private File findFile(File base, String path, boolean cs) { 1525 if (FileUtils.isAbsolutePath(path)) { 1526 if (base == null) { 1527 String [] s = FILE_UTILS.dissect(path); 1528 base = new File (s[0]); 1529 path = s[1]; 1530 } else { 1531 File f = FILE_UTILS.normalize(path); 1532 String s = FILE_UTILS.removeLeadingPath(base, f); 1533 if (s.equals(f.getAbsolutePath())) { 1534 return null; 1536 } 1537 path = s; 1538 } 1539 } 1540 return findFile(base, SelectorUtils.tokenizePath(path), cs); 1541 } 1542 1543 1554 private File findFile(File base, Vector pathElements, boolean cs) { 1555 if (pathElements.size() == 0) { 1556 return base; 1557 } 1558 String current = (String ) pathElements.remove(0); 1559 if (base == null) { 1560 return findFile(new File (current), pathElements, cs); 1561 } 1562 if (!base.isDirectory()) { 1563 return null; 1564 } 1565 String [] files = list(base); 1566 if (files == null) { 1567 throw new BuildException("IO error scanning directory " 1568 + base.getAbsolutePath()); 1569 } 1570 boolean[] matchCase = cs ? CS_SCAN_ONLY : CS_THEN_NON_CS; 1571 for (int i = 0; i < matchCase.length; i++) { 1572 for (int j = 0; j < files.length; j++) { 1573 if (matchCase[i] ? files[j].equals(current) 1574 : files[j].equalsIgnoreCase(current)) { 1575 return findFile(new File (base, files[j]), pathElements, cs); 1576 } 1577 } 1578 } 1579 return null; 1580 } 1581 1582 1589 private boolean isSymlink(File base, String path) { 1590 return isSymlink(base, SelectorUtils.tokenizePath(path)); 1591 } 1592 1593 1600 private boolean isSymlink(File base, Vector pathElements) { 1601 if (pathElements.size() > 0) { 1602 String current = (String ) pathElements.remove(0); 1603 try { 1604 return FILE_UTILS.isSymbolicLink(base, current) 1605 || isSymlink(new File (base, current), pathElements); 1606 } catch (IOException ioe) { 1607 String msg = "IOException caught while checking " 1608 + "for links, couldn't get canonical path!"; 1609 System.err.println(msg); 1611 } 1612 } 1613 return false; 1614 } 1615 1616 1624 private boolean hasBeenScanned(String vpath) { 1625 return !scannedDirs.add(vpath); 1626 } 1627 1628 1633 Set getScannedDirs() { 1634 return scannedDirs; 1635 } 1636 1637 1642 private synchronized void clearCaches() { 1643 fileListMap.clear(); 1644 includeNonPatterns.clear(); 1645 excludeNonPatterns.clear(); 1646 includePatterns = null; 1647 excludePatterns = null; 1648 areNonPatternSetsReady = false; 1649 } 1650 1651 1657 private synchronized void ensureNonPatternSetsReady() { 1658 if (!areNonPatternSetsReady) { 1659 includePatterns = fillNonPatternSet(includeNonPatterns, includes); 1660 excludePatterns = fillNonPatternSet(excludeNonPatterns, excludes); 1661 areNonPatternSetsReady = true; 1662 } 1663 } 1664 1665 1673 private String [] fillNonPatternSet(Set set, String [] patterns) { 1674 ArrayList al = new ArrayList (patterns.length); 1675 for (int i = 0; i < patterns.length; i++) { 1676 if (!SelectorUtils.hasWildcards(patterns[i])) { 1677 set.add(isCaseSensitive() ? patterns[i] 1678 : patterns[i].toUpperCase()); 1679 } else { 1680 al.add(patterns[i]); 1681 } 1682 } 1683 return set.size() == 0 ? patterns 1684 : (String []) al.toArray(new String [al.size()]); 1685 } 1686 1687} 1688 | Popular Tags |