| 1 18 19 package org.apache.tools.ant.util; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.InputStreamReader ; 25 import java.io.Reader ; 26 import java.io.UnsupportedEncodingException ; 27 import java.io.Writer ; 28 import java.io.OutputStream ; 29 import java.net.MalformedURLException ; 30 import java.net.URL ; 31 import java.text.DecimalFormat ; 32 import java.util.ArrayList ; 33 import java.util.Arrays ; 34 import java.util.Iterator ; 35 import java.util.List ; 36 import java.util.Random ; 37 import java.util.Stack ; 38 import java.util.StringTokenizer ; 39 import java.util.Vector ; 40 import org.apache.tools.ant.BuildException; 41 import org.apache.tools.ant.PathTokenizer; 42 import org.apache.tools.ant.Project; 43 import org.apache.tools.ant.taskdefs.condition.Os; 44 import org.apache.tools.ant.types.FilterSetCollection; 45 import org.apache.tools.ant.types.resources.FileResource; 46 import org.apache.tools.ant.launch.Locator; 47 48 55 public class FileUtils { 56 57 private static final FileUtils PRIMARY_INSTANCE = new FileUtils(); 58 59 private static Random rand = new Random (System.currentTimeMillis() 61 + Runtime.getRuntime().freeMemory()); 62 63 private static boolean onNetWare = Os.isFamily("netware"); 64 private static boolean onDos = Os.isFamily("dos"); 65 private static boolean onWin9x = Os.isFamily("win9x"); 66 private static boolean onWindows = Os.isFamily("windows"); 67 68 static final int BUF_SIZE = 8192; 69 70 71 74 public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000; 75 76 79 public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000; 80 81 86 public static final long NTFS_FILE_TIMESTAMP_GRANULARITY = 1; 87 88 89 95 private Object cacheFromUriLock = new Object (); 96 private String cacheFromUriRequest = null; 97 private String cacheFromUriResponse = null; 98 99 107 public static FileUtils newFileUtils() { 108 return new FileUtils(); 109 } 110 111 117 public static FileUtils getFileUtils() { 118 return PRIMARY_INSTANCE; 119 } 120 121 124 protected FileUtils() { 125 } 126 127 135 public URL getFileURL(File file) throws MalformedURLException { 136 return new URL (toURI(file.getAbsolutePath())); 137 } 138 139 150 public void copyFile(String sourceFile, String destFile) 151 throws IOException { 152 copyFile(new File (sourceFile), new File (destFile), null, false, false); 153 } 154 155 167 public void copyFile(String sourceFile, String destFile, 168 FilterSetCollection filters) 169 throws IOException { 170 copyFile(new File (sourceFile), new File (destFile), filters, 171 false, false); 172 } 173 174 189 public void copyFile(String sourceFile, String destFile, FilterSetCollection filters, 190 boolean overwrite) throws IOException { 191 copyFile(new File (sourceFile), new File (destFile), filters, 192 overwrite, false); 193 } 194 195 215 public void copyFile(String sourceFile, String destFile, FilterSetCollection filters, 216 boolean overwrite, boolean preserveLastModified) 217 throws IOException { 218 copyFile(new File (sourceFile), new File (destFile), filters, 219 overwrite, preserveLastModified); 220 } 221 222 245 public void copyFile(String sourceFile, String destFile, 246 FilterSetCollection filters, boolean overwrite, 247 boolean preserveLastModified, String encoding) 248 throws IOException { 249 copyFile(new File (sourceFile), new File (destFile), filters, 250 overwrite, preserveLastModified, encoding); 251 } 252 253 280 public void copyFile(String sourceFile, String destFile, 281 FilterSetCollection filters, Vector filterChains, 282 boolean overwrite, boolean preserveLastModified, 283 String encoding, Project project) 284 throws IOException { 285 copyFile(new File (sourceFile), new File (destFile), filters, 286 filterChains, overwrite, preserveLastModified, 287 encoding, project); 288 } 289 290 317 public void copyFile(String sourceFile, String destFile, 318 FilterSetCollection filters, Vector filterChains, 319 boolean overwrite, boolean preserveLastModified, 320 String inputEncoding, String outputEncoding, 321 Project project) 322 throws IOException { 323 copyFile(new File (sourceFile), new File (destFile), filters, 324 filterChains, overwrite, preserveLastModified, 325 inputEncoding, outputEncoding, project); 326 } 327 328 339 public void copyFile(File sourceFile, File destFile) throws IOException { 340 copyFile(sourceFile, destFile, null, false, false); 341 } 342 343 355 public void copyFile(File sourceFile, File destFile, FilterSetCollection filters) 356 throws IOException { 357 copyFile(sourceFile, destFile, filters, false, false); 358 } 359 360 375 public void copyFile(File sourceFile, File destFile, FilterSetCollection filters, 376 boolean overwrite) throws IOException { 377 copyFile(sourceFile, destFile, filters, overwrite, false); 378 } 379 380 400 public void copyFile(File sourceFile, File destFile, FilterSetCollection filters, 401 boolean overwrite, boolean preserveLastModified) 402 throws IOException { 403 copyFile(sourceFile, destFile, filters, overwrite, 404 preserveLastModified, null); 405 } 406 407 431 public void copyFile(File sourceFile, File destFile, 432 FilterSetCollection filters, boolean overwrite, 433 boolean preserveLastModified, String encoding) 434 throws IOException { 435 copyFile(sourceFile, destFile, filters, null, overwrite, 436 preserveLastModified, encoding, null); 437 } 438 439 465 public void copyFile(File sourceFile, File destFile, 466 FilterSetCollection filters, Vector filterChains, 467 boolean overwrite, boolean preserveLastModified, 468 String encoding, Project project) 469 throws IOException { 470 copyFile(sourceFile, destFile, filters, filterChains, 471 overwrite, preserveLastModified, encoding, encoding, project); 472 } 473 474 502 public void copyFile(File sourceFile, File destFile, 503 FilterSetCollection filters, Vector filterChains, 504 boolean overwrite, boolean preserveLastModified, 505 String inputEncoding, String outputEncoding, 506 Project project) 507 throws IOException { 508 ResourceUtils.copyResource( 509 new FileResource(sourceFile), new FileResource(destFile), 510 filters, filterChains, overwrite, preserveLastModified, 511 inputEncoding, outputEncoding, project); 512 } 513 514 516 524 public void setFileLastModified(File file, long time) { 525 ResourceUtils.setLastModified(new FileResource(file), time); 526 } 527 528 549 public File resolveFile(File file, String filename) { 550 if (!isAbsolutePath(filename)) { 551 char sep = File.separatorChar; 552 filename = filename.replace('/', sep).replace('\\', sep); 553 if (isContextRelativePath(filename)) { 554 file = null; 555 String udir = System.getProperty("user.dir"); 558 if (filename.charAt(0) == sep && udir.charAt(0) == sep) { 559 filename = dissect(udir)[0] + filename.substring(1); 560 } 561 } 562 filename = new File (file, filename).getAbsolutePath(); 563 } 564 return normalize(filename); 565 } 566 567 578 public static boolean isContextRelativePath(String filename) { 579 if (!(onDos || onNetWare) || filename.length() == 0) { 580 return false; 581 } 582 char sep = File.separatorChar; 583 filename = filename.replace('/', sep).replace('\\', sep); 584 char c = filename.charAt(0); 585 int len = filename.length(); 586 return (c == sep && (len == 1 || filename.charAt(1) != sep)) 587 || (Character.isLetter(c) && len > 1 588 && filename.indexOf(':') == 1 589 && (len == 2 || filename.charAt(2) != sep)); 590 } 591 592 602 public static boolean isAbsolutePath(String filename) { 603 int len = filename.length(); 604 if (len == 0) { 605 return false; 606 } 607 char sep = File.separatorChar; 608 filename = filename.replace('/', sep).replace('\\', sep); 609 char c = filename.charAt(0); 610 if (!(onDos || onNetWare)) { 611 return (c == sep); 612 } 613 if (c == sep) { 614 if (!(onDos && len > 4 && filename.charAt(1) == sep)) { 615 return false; 616 } 617 int nextsep = filename.indexOf(sep, 2); 618 return nextsep > 2 && nextsep + 1 < len; 619 } 620 int colon = filename.indexOf(':'); 621 return (Character.isLetter(c) && colon == 1 622 && filename.length() > 2 && filename.charAt(2) == sep) 623 || (onNetWare && colon > 0); 624 } 625 626 643 public static String translatePath(String toProcess) { 644 if (toProcess == null || toProcess.length() == 0) { 645 return ""; 646 } 647 StringBuffer path = new StringBuffer (toProcess.length() + 50); 648 PathTokenizer tokenizer = new PathTokenizer(toProcess); 649 while (tokenizer.hasMoreTokens()) { 650 String pathComponent = tokenizer.nextToken(); 651 pathComponent = pathComponent.replace('/', File.separatorChar); 652 pathComponent = pathComponent.replace('\\', File.separatorChar); 653 if (path.length() != 0) { 654 path.append(File.pathSeparatorChar); 655 } 656 path.append(pathComponent); 657 } 658 return path.toString(); 659 } 660 661 680 public File normalize(final String path) { 681 Stack s = new Stack (); 682 String [] dissect = dissect(path); 683 s.push(dissect[0]); 684 685 StringTokenizer tok = new StringTokenizer(dissect[1], File.separator); 686 while (tok.hasMoreTokens()) { 687 String thisToken = tok.nextToken(); 688 if (".".equals(thisToken)) { 689 continue; 690 } else if ("..".equals(thisToken)) { 691 if (s.size() < 2) { 692 return new File (path); 694 } 695 s.pop(); 696 } else { s.push(thisToken); 698 } 699 } 700 StringBuffer sb = new StringBuffer (); 701 for (int i = 0; i < s.size(); i++) { 702 if (i > 1) { 703 sb.append(File.separatorChar); 706 } 707 sb.append(s.elementAt(i)); 708 } 709 return new File (sb.toString()); 710 } 711 712 719 public String [] dissect(String path) { 720 char sep = File.separatorChar; 721 path = path.replace('/', sep).replace('\\', sep); 722 723 if (!isAbsolutePath(path)) { 725 throw new BuildException(path + " is not an absolute path"); 726 } 727 String root = null; 728 int colon = path.indexOf(':'); 729 if (colon > 0 && (onDos || onNetWare)) { 730 731 int next = colon + 1; 732 root = path.substring(0, next); 733 char[] ca = path.toCharArray(); 734 root += sep; 735 next = (ca[next] == sep) ? next + 1 : next; 737 738 StringBuffer sbPath = new StringBuffer (); 739 for (int i = next; i < ca.length; i++) { 741 if (ca[i] != sep || ca[i - 1] != sep) { 742 sbPath.append(ca[i]); 743 } 744 } 745 path = sbPath.toString(); 746 } else if (path.length() > 1 && path.charAt(1) == sep) { 747 int nextsep = path.indexOf(sep, 2); 749 nextsep = path.indexOf(sep, nextsep + 1); 750 root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path; 751 path = path.substring(root.length()); 752 } else { 753 root = File.separator; 754 path = path.substring(1); 755 } 756 return new String [] {root, path}; 757 } 758 759 768 public String toVMSPath(File f) { 769 String osPath; 771 String path = normalize(f.getAbsolutePath()).getPath(); 772 String name = f.getName(); 773 boolean isAbsolute = path.charAt(0) == File.separatorChar; 774 boolean isDirectory = f.isDirectory() 776 && !name.regionMatches(true, name.length() - 4, ".DIR", 0, 4); 777 778 String device = null; 779 StringBuffer directory = null; 780 String file = null; 781 782 int index = |