1 4 5 9 10 package org.openlaszlo.utils; 11 12 import org.openlaszlo.server.LPS; 13 14 import java.io.File ; 15 import java.io.RandomAccessFile ; 16 import java.io.IOException ; 17 import java.io.FileNotFoundException ; 18 import java.io.FilenameFilter ; 19 import java.io.FileInputStream ; 20 import java.io.InputStream ; 21 import java.io.OutputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.FilterOutputStream ; 24 import java.io.FilterInputStream ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.PushbackInputStream ; 27 28 import java.io.ByteArrayInputStream ; 29 30 import java.io.Writer ; 31 import java.io.Writer ; 32 import java.io.Reader ; 33 import java.io.StringWriter ; 34 import java.util.*; 35 import java.util.zip.*; 36 37 import org.apache.log4j.*; 38 import org.apache.oro.text.regex.*; 39 40 class AbsolutePathnameTester { 43 static boolean test(List dirs) { 44 if (!dirs.isEmpty()) { 45 String dir = (String ) dirs.get(0); 46 return new File (dir + "/").isAbsolute(); 51 } 52 return false; 53 } 54 } 55 56 62 public abstract class FileUtils { 63 64 private static Logger mLogger = Logger.getLogger(FileUtils.class); 65 66 public static final String GZIP = "gzip"; 68 public static final String DEFLATE = "deflate"; 69 public static final int GZIP_HEADER_LENGTH = 10; 70 public static final int MIN_GZIP_PEEK = 2; 71 public static final int MIN_SWF_PEEK = 9; 72 73 public static int BUFFER_SIZE = 10240; 74 public static int THROTTLE = 0; 75 76 static { 77 try { 78 String throttle = LPS.getProperty("lps.throttle"); 79 BUFFER_SIZE = Integer.parseInt(LPS.getProperty("buffer.size", "10240")); 80 if (throttle != null) { 81 THROTTLE = Integer.parseInt(throttle); 82 BUFFER_SIZE = 1024; 83 mLogger.info("throttle " + throttle); 84 } 85 86 87 } catch (RuntimeException e) { 88 mLogger.error("Exception initializing FileUtils", e); 89 } catch (Exception e) { 90 mLogger.error("Exception initializing FileUtils", e); 91 } 92 } 93 94 99 public static byte[] readFileBytes(File file) 100 throws IOException 101 { 102 java.io.InputStream istr = new java.io.FileInputStream (file); 103 byte bytes[] = new byte[istr.available()]; 104 istr.read(bytes); 105 istr.close(); 106 return bytes; 107 } 108 109 114 115 public static String readFileString(File file) 116 throws IOException 117 { 118 byte data[] = readFileBytes(file); 119 return new String (data, "UTF-8"); 120 } 121 122 128 129 public static String readFileString(File file, String defaultEncoding) 130 throws IOException 131 { 132 Reader reader = makeXMLReaderForFile(file.getAbsolutePath(), defaultEncoding); 133 StringWriter s = new StringWriter (); 134 send(reader, s); 135 reader.close(); 136 return s.toString(); 137 } 138 139 140 147 public static String getXMLEncodingFromFile(String pathname, String defaultEncoding) 148 throws IOException { 149 java.io.FileInputStream ifs = new java.io.FileInputStream (pathname); 150 ByteArrayOutputStream bout = new ByteArrayOutputStream (); 151 send(ifs, bout); 152 Perl5Matcher matcher = new Perl5Matcher(); 153 try { 154 Perl5Compiler compiler = new Perl5Compiler(); 155 Pattern pattern = compiler.compile("[^<]*\\s*<[?]xml\\s+[^>]*encoding=[\"'](.*)['\"][^>]*?>"); 156 if (matcher.contains(new String (bout.toByteArray()), pattern)) { 157 MatchResult result = matcher.getMatch(); 158 String encoding = result.group(1); 159 return encoding; 160 } else { 161 return "UTF-8"; 162 } 163 } catch (MalformedPatternException e) { 164 throw new RuntimeException (e.getMessage()); 165 } 166 } 167 168 175 public static Reader makeXMLReaderForFile (String pathname, String defaultEncoding) 176 throws IOException { 177 String encoding = getXMLEncodingFromFile(pathname, defaultEncoding); 178 java.io.FileInputStream ifs = new java.io.FileInputStream (pathname); 179 java.io.PushbackInputStream pbis = new java.io.PushbackInputStream (ifs, 1024); 180 FileUtils.stripByteOrderMark(pbis); 185 return new java.io.InputStreamReader (pbis, encoding); 186 } 187 188 193 public static String stripByteOrderMark (PushbackInputStream pbis) throws IOException { 194 int c1 = pbis.read(); 198 int c2 = pbis.read(); 199 int c3 = pbis.read(); 200 if (c1 == 0xFF & c2 == 0xFE) { 201 pbis.unread(c3); 204 return "UTF-16BE"; 205 } else if (c1 == 0xFE & c2 == 0xFF) { 206 pbis.unread(c3); 209 return "UTF-16LE"; 210 } else if (c1 == 0xEF && c2 == 0xBB && c3 == 0xBF) { 211 return "UTF-8"; 214 } else { 215 pbis.unread(c3); 217 pbis.unread(c2); 218 pbis.unread(c1); 219 return null; 220 } 221 } 222 223 229 static public long fileSize(File file) 230 throws IOException , FileNotFoundException { 231 232 RandomAccessFile raf = null; 233 try { 234 raf = new RandomAccessFile (file, "r"); 235 return raf.length(); 236 } finally { 237 if (raf != null) { 238 try { 239 raf.close(); 240 } catch (Exception e) { 241 mLogger.warn("ignoring exception while closing random access file: ", e); 242 } 243 } 244 } 245 } 246 250 static public long getSize(File file) { 251 try { 252 return fileSize(file); 253 } catch (Exception e) { 254 return -1; 255 } 256 } 257 258 264 public static String getBase(String pathname) { 265 int pos = pathname.lastIndexOf('.'); 266 if (pos >= 0) { 267 return pathname.substring(0, pos); 268 } else { 269 return pathname; 270 } 271 } 272 273 277 public static String getExtension(String pathname) { 278 int pos = pathname.lastIndexOf('.'); 279 if (pos >= 0 && pos != pathname.length() - 1) { 280 return pathname.substring(pos+1); 281 } 282 return ""; 283 } 284 285 291 public static String fixAbsWindowsPaths(String src) { 292 293 if (File.separatorChar == '/') 295 return src; 296 297 if (src.length() < 2) 299 return src; 300 301 if (src.charAt(1) != ':') 303 return src; 304 305 char c = src.charAt(0); 307 int t = Character.getType(c); 308 boolean isAscii = (t == Character.UPPERCASE_LETTER || 309 t == Character.LOWERCASE_LETTER); 310 if (!isAscii) { 311 return src; 312 } 313 314 return src.substring(0,1) + src.substring(2); 316 } 317 318 323 public static void makeFileAndParentDirs(File file) 324 throws IOException { 325 File dir = file.getParentFile(); 326 if (dir != null) 327 dir.mkdirs(); 328 file.createNewFile(); 329 } 330 331 335 public static boolean rmTree(File file) { 336 boolean delTreeOk = true; 337 boolean delFileOk = true; 338 File [] files = file.listFiles(); if (files != null) { 340 for (Iterator iter = Arrays.asList(files).iterator(); 341 iter.hasNext(); ) { 342 if (! rmTree((File ) iter.next())) 343 delTreeOk = false; 344 } 345 } 346 delFileOk = file.delete(); 347 348 return (delFileOk && delTreeOk); 349 } 350 351 359 public static int send(InputStream input, OutputStream output) 360 throws IOException { 361 362 int available = input.available(); 363 int bsize; 364 if (available == 0) { 365 bsize = BUFFER_SIZE; 366 } else { 367 bsize = Math.min(input.available(), BUFFER_SIZE); 368 } 369 return send(input, output, bsize); 370 } 371 372 375 public static class StreamWritingException extends IOException { 376 public StreamWritingException (String s) 377 { 378 super(s); 379 } 380 } 381 382 385 public static class StreamReadingException extends IOException { 386 public StreamReadingException (String s) 387 { 388 super(s); 389 } 390 } 391 392 393 401 public static int send(Reader input, Writer output) 402 throws IOException { 403 int bsize = BUFFER_SIZE; 404 return send(input, output, bsize); 405 } 406 407 408 418 public static int send(Reader input, Writer output, int size) 419 throws IOException { 420 int c = 0; 421 char[] buffer = new char[size]; 422 int b = 0; 423 while((b = input.read(buffer)) > 0) { 424 c += b; 425 output.write(buffer, 0, b); 426 } 427 return c; 428 } 429 430 431 441 public static int send(InputStream input, OutputStream output, int size) 442 throws IOException { 443 int c = 0; 444 byte[] buffer = new byte[size]; 445 int b = 0; 446 while((b = input.read(buffer)) > 0) { 447 c += b; 448 output.write(buffer, 0, b); 449 } 450 return c; 451 } 452 453 461 public static int sendToStream(InputStream input, OutputStream output) 462 throws IOException { 463 464 int available = input.available(); 465 int bsize; 466 if (available == 0) { 467 bsize = BUFFER_SIZE; 468 } else { 469 bsize = Math.min(input.available(), BUFFER_SIZE); 470 } 471 return sendToStream(input, output, bsize); 472 } 473 474 484 public static int sendToStream(InputStream input, 485 OutputStream output, int size) 486 throws IOException { 487 int c = 0; 488 byte[] buffer = new byte[size]; 489 int b = 0; 490 while(true) { 491 try { 492 if ((b = input.read(buffer)) <= 0) { 494 return c; 495 } 496 } catch (IOException e) { 497 throw new StreamReadingException(e.getMessage()); 498 } 499 c += b; 500 try { 501 output.write(buffer, 0, b); 502 } catch (IOException e) { 503 throw new StreamWritingException(e.getMessage()); 504 } 505 if (THROTTLE != 0) { 506 try { 507 mLogger.info("Sleeping " + THROTTLE + " msecs "); 508 Thread.currentThread().sleep(THROTTLE); 509 } catch (InterruptedException e) { 510 mLogger.warn("interrupted during sleep", e); 511 } 512 } 513 } 514 } 515 516 523 public static int escapeHTMLAndSend(InputStream input, OutputStream output) 524 throws IOException { 525 526 int available = input.available(); 527 int bsize; 528 if (available == 0) { 529 bsize = BUFFER_SIZE; 530 } else { 531 bsize = Math.min(input.available(), BUFFER_SIZE); 532 } 533 return escapeHTMLAndSend(input, output, bsize); 534 } 535 544 public static int escapeHTMLAndSend(InputStream input, OutputStream output, int size) 545 throws IOException { 546 int c = 0; 547 byte[] buffer = new byte[size]; 548 byte[] buffer2 = new byte[size*4]; int b = 0; 550 int b2 = 0; 551 while((b = input.read(buffer)) > 0) { 552 b2 = escapeHTML(buffer, b, buffer2); 553 c += b2; 554 output.write(buffer2, 0, b2); 555 } 556 return c; 557 } 558 559 568 public static int escapeHTML(byte[] ib, int buflen, byte[] ob) { 569 int bc = 0; 570 for(int i = 0; i < buflen; i++) { 571 if (ib[i] == '<') { 572 ob[bc++] = '&'; 573 ob[bc++] = 'l'; 574 ob[bc++] = 't'; 575 ob[bc++] = ';'; 576 } else if (ib[i] == '>') { 577 ob[bc++] = '&'; 578 ob[bc++] = 'g'; 579 ob[bc++] = 't'; 580 ob[bc++] = ';'; 581 } else { 582 ob[bc++] = ib[i]; 583 } 584 } 585 586 return bc; 587 } 588 589 public static class RelativizationError extends Error { 590 RelativizationError(String message) { 591 super(message); 592 } 593 } 594 595 598 public static String adjustRelativePath(String path, 599 String source, String dest) 600 throws RelativizationError 601 { 602 final String separator = "/"; 603 if (path.endsWith(separator)) { 604 return path; 605 } 606 if (source.endsWith(separator)) { 607 source = source.substring(0, source.length() - 1); 608 } 609 if (dest.endsWith(separator)) { 610 dest = dest.substring(0, dest.length() - 1); 611 } 612 List sourcedirs = new Vector(Arrays.asList(StringUtils.split(source, separator))); 613 List destdirs = new Vector(Arrays.asList(StringUtils.split(dest, separator))); 614 normalizePath(sourcedirs); 615 normalizePath(destdirs); 616 while (!sourcedirs.isEmpty() && !destdirs.isEmpty() && 618 ((String ) sourcedirs.get(0)).equals((String ) destdirs.get(0))) { 619 sourcedirs.remove(0); 620 destdirs.remove(0); 621 } 622 if (AbsolutePathnameTester.test(sourcedirs) || 630 AbsolutePathnameTester.test(destdirs)) { 631 throw new RelativizationError( 632 "can't create a pathname relative to " +dest + 633 " that refers to a file relative to "+ source); 634 } 635 List components = new Vector(); 636 for (Iterator iter = sourcedirs.iterator(); iter.hasNext(); ) { 638 iter.next(); 639 components.add(".."); 640 } 641 for (Iterator iter = destdirs.iterator(); iter.hasNext(); ) { 643 components.add(iter.next()); 644 } 645 components.add(path); 646 return StringUtils.join(components, separator); 647 } 648 649 655 public static String relativePath(File file, String directoryName) { 656 try { 657 String fileName = file.getCanonicalPath().replace('\\', '/'); 658 String dirName = new File (directoryName).getCanonicalPath().replace('\\', '/'); 659 if (!fileName.startsWith(dirName)) { 660 return fileName; 661 } 662 return fileName.substring(dirName.length()); 663 } catch (IOException ioe) { 664 throw new ChainedException(ioe); 665 } 666 } 667 668 674 public static String relativePath(String filename, String directoryName) { 675 return relativePath(new File (filename), directoryName); 676 } 677 678 public static String toURLPath(File file) { 679 return StringUtils.join(StringUtils.split(file.getPath(), 681 file.separator), 682 "/"); 683 } 684 685 686 public static void normalizePath(List path) { 687 for (int i = 0; i < path.size(); i++) { 688 String component = (String ) path.get(i); 689 if (component.equals(".") || component.equals("")) { 690 path.remove(i--); 691 } else if (component.equals("..") && i > 0) { 692 path.remove(i--); 693 path.remove(i--); 694 } 695 } 696 } 697 698 705 static public void encode(File inputFile, File outputFile, String encoding) 706 throws IOException { 707 708 FileInputStream in = null; 709 710 try { 711 in = new FileInputStream (inputFile); 712 encode(in, outputFile, encoding); 713 } finally { 714 if (in != null) 715 in.close(); 716 } 717 } 718 719 726 static public void decode(File inputFile, File outputFile, String encoding) 727 throws IOException { 728 729 mLogger.debug("Starting decoding from " + encoding); 730 FilterInputStream in = null; 731 OutputStream out = new FileOutputStream (outputFile); 732 InputStream ins = new FileInputStream (inputFile); 733 734 try { 735 if (encoding.equals(GZIP)) { 736 in = new GZIPInputStream(ins); 737 } else if (encoding.equals(DEFLATE)) { 738 in = new InflaterInputStream(ins); 739 } else { 740 String message = "Unsuppored encoding: " + encoding; 741 mLogger.error(message); 742 throw new ChainedException(message); 743 } 744 745 int b = FileUtils.send(in, out, BUFFER_SIZE); 749 mLogger.debug("decoded into " + b + " bytes" ); 750 } finally { 751 close(in); 752 close(ins); 753 close(out); 754 } 755 mLogger.debug("Done decoding from " + encoding); 756 } 757 758 765 static public void encode(InputStream input, File outputFile, String encoding) 766 throws IOException { 767 768 FileOutputStream out = null; 769 FilterOutputStream filter = null; 770 771 mLogger.debug("Encoding into " + encoding); 772 773 try { 774 FileUtils.makeFileAndParentDirs(outputFile); 775 776 out = new FileOutputStream (outputFile); 777 778 if (encoding.equals(GZIP)) { 779 filter = new GZIPOutputStream(out); 780 } else if (encoding.equals(DEFLATE)) { 781 filter = new DeflaterOutputStream(out); 782 } else { 783 String message = "Unsupported encoding: " + encoding; 784 mLogger.error(message); 785 throw new ChainedException(message); 786 } 787 788 FileUtils.send(input, filter, BUFFER_SIZE); 789 790 } finally { 791 if (filter != null) 792 close(filter); 793 if (out != null) 794 close(out); 795 } 796 797 mLogger.debug("Done encoding into " + encoding); 798 } 799 800 805 static public void close(InputStream in) { 806 try { 807 if (in != null) { 808 in.close(); 809 } 810 } catch (Exception e) { 811 } 812 } 813 814 819 static public void close(OutputStream out) { 820 try { 821 if (out != null) { 822 out.close(); 823 } 824 } catch (Exception e) { 825 } 826 } 827 828 833 static public void close(Writer w) { 834 try { 835 if (w != null) { 836 w.close(); 837 } 838 } catch (Exception e) { 839 } 840 } 841 842 849 static public boolean deleteFiles(File dir, String [] fileNames) { 850 boolean ok = true; 851 852 for(int i = 0; i < fileNames.length; i++) { 853 File file = new File (dir + File.separator + fileNames[i]); 854 try { 855 if (!file.isDirectory()) { 856 file.delete(); 857 } 858 } catch (Throwable e) { 859 mLogger.error("can't delete file: " + fileNames[i]); 860 ok = false; 861 } 862 } 863 return ok; 864 } 865 866 873 static public boolean deleteFiles(File dir) { 874 875 if (!dir.isDirectory()) { 876 return false; 877 } 878 String [] fileNames = dir.list(); 879 880 return deleteFiles(dir, fileNames); 881 } 882 883 889 static public boolean deleteFilesStartingWith(File dir, String name) { 890 891 boolean ok = true; 892 893 897 class StartsWithNameFilter implements FilenameFilter { 898 final String _name; 899 900 StartsWithNameFilter(String n) { 901 _name = n; 902 } 903 public boolean accept(File d, String n) { 904 return (n.startsWith(_name)); 905 } 906 } 907 908 String [] fileNames = dir.list(new StartsWithNameFilter(name)); 909 910 return deleteFiles(dir, fileNames); 911 } 912 } 913 | Popular Tags |