1 23 24 25 package com.sun.jdo.api.persistence.enhancer; 26 27 import java.io.IOException ; 30 import java.io.FileNotFoundException ; 31 import java.io.File ; 32 import java.io.InputStream ; 33 import java.io.OutputStream ; 34 import java.io.FileInputStream ; 35 import java.io.FileOutputStream ; 36 import java.io.DataInputStream ; 37 import java.io.DataOutputStream ; 38 import java.io.BufferedInputStream ; 39 import java.io.BufferedOutputStream ; 40 import java.io.PrintWriter ; 41 import java.io.FileReader ; 42 import java.io.BufferedReader ; 43 44 import java.util.Map ; 47 import java.util.Collection ; 48 import java.util.Enumeration ; 49 import java.util.Iterator ; 50 import java.util.ArrayList ; 51 import java.util.HashMap ; 52 import java.util.Hashtable ; 53 import java.util.Properties ; 54 import java.util.StringTokenizer ; 55 56 import java.util.zip.ZipFile ; 57 import java.util.zip.ZipEntry ; 58 import java.util.zip.ZipInputStream ; 59 import java.util.zip.ZipOutputStream ; 60 import java.util.zip.ZipException ; 61 62 import java.net.URL ; 63 64 import com.sun.jdo.api.persistence.model.Model; 65 66 71 import com.sun.jdo.api.persistence.enhancer.util.Support; 73 74 76 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaData; 77 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataModelImpl; 78 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataPropertyImpl; 79 import com.sun.jdo.api.persistence.enhancer.meta.JDOMetaDataTimer; 80 81 84 85 87 91 92 126 127 130 public class Main 131 { 132 133 134 137 private ByteCodeEnhancer enhancer = null; 138 139 140 143 private final PrintWriter outMessages = new PrintWriter (System.out, true); 144 145 146 149 private final PrintWriter outErrors = new PrintWriter (System.err, true); 150 151 152 155 private final CmdLineOptions cmdLineOpts = new CmdLineOptions (); 156 157 158 161 public Main() { 162 } 163 164 165 168 public static void main(String [] argv) { 169 final Main main = new Main(); 171 try { 172 main.process(argv); 175 } catch (RuntimeException tt) { 176 System.err.println("Exception occurred while postprocessing:"); 179 tt.printStackTrace(System.err); 180 throw tt; 182 } finally { 183 if (main.cmdLineOpts.doTiming) { 185 Support.timer.print(); 186 } 187 } 188 } 189 190 193 public int process(String [] argv) { 195 ArrayList cNames = new ArrayList (); 197 int res = processArgs(argv, cNames); 199 if (res != 0) { 200 printMessage ("aborted with errors."); return res; 203 } 204 205 try { 207 if (this.cmdLineOpts.doTiming) { 208 Support.timer.push("Main.process(String[])"); } 210 211 enhanceInputFiles (cNames); 214 217 218 printMessage ("done."); return 0; 220 } finally { 221 if (this.cmdLineOpts.doTiming) { 222 Support.timer.pop(); 223 } 224 } 225 } 226 227 230 protected int processArgs(String [] argv, 233 Collection cNames) { 235 argv = preprocess(argv); 236 237 244 245 250 251 Properties jdoMetaDataProperties = null; 253 254 for (int i=0; i<argv.length; i++) { 255 257 String arg = argv[i]; 258 276 if (arg.equals("-v") || arg.equals("-verbose")) { this.cmdLineOpts.verbose = true; 279 this.cmdLineOpts.quiet = false; 280 continue; 281 } 282 if (arg.equals("-q") || arg.equals("-quiet")) { this.cmdLineOpts.quiet = true; 285 this.cmdLineOpts.verbose = false; 286 continue; 287 } 288 if (arg.equals("-f") || arg.equals("-force")) { this.cmdLineOpts.forceWrite = true; 291 continue; 292 } 293 300 330 if (arg.equals("-nowrite")) { this.cmdLineOpts.noWrite = true; 332 continue; 333 } 334 341 348 355 370 if (arg.equals("-d") || arg.equals("-dest")) { if (argv.length-i < 2) { 373 printError ("Missing argument to the -dest option", null); usage(); 375 } 376 this.cmdLineOpts.destinationDirectory = argv[++i]; 377 continue; 378 } 379 400 413 if (arg.equals("-t") || arg.equals("--doTiming")) { this.cmdLineOpts.doTiming = true; 417 continue; 419 } 420 if (arg.equals("-jp") || arg.equals("--jdoProperties")) { if (argv.length-i < 2) { 424 printError("Missing argument to the -jp/--jdoProperties option", null); usage(); 426 } 427 try { 428 jdoMetaDataProperties = new Properties (); 429 jdoMetaDataProperties.load(new FileInputStream (argv[++i])); 430 } catch (IOException ex) { 431 printError("Cannot read JDO meta data properties from file", ex); usage(); 433 } 434 continue; 435 } 436 if (arg.length() > 0 && arg.charAt(0) == '-') { 437 printError("Unrecognized option:" + arg, null); usage(); 439 } 440 if (arg.length() == 0) { 441 printMessage ("Empty file name encountered on the command line."); } 443 444 cNames.add(arg); 446 461 } 462 463 this.cmdLineOpts.quiet = false; 466 469 473 474 480 481 if (this.cmdLineOpts.destinationDirectory == null) { 483 if (argv.length > 0) 484 printError("No -dest output directory was specified", null); usage(); 486 } 487 488 JDOMetaData jdoMetaData; 490 if (jdoMetaDataProperties != null) { 491 printMessage("using JDO meta-data from properties"); jdoMetaData = new JDOMetaDataPropertyImpl(jdoMetaDataProperties, this.outMessages); 493 } else { 494 printMessage("using JDO meta-data from Model.Enhancer"); jdoMetaData = new JDOMetaDataModelImpl(Model.ENHANCER, this.outMessages); 496 } 497 if (this.cmdLineOpts.doTiming) { 499 jdoMetaData = new JDOMetaDataTimer(jdoMetaData); 501 } 502 503 try 504 { 505 this.enhancer = createEnhancer (jdoMetaData); 506 } 507 catch (Exception ex) 508 { 509 printError ("Error creating the enhancer", ex); 510 } 511 512 513 522 523 533 534 return 0; 536 } 537 538 540 544 private String [] preprocess(String [] args) { 545 ArrayList argVec = new ArrayList (); 546 for (int i=0; i<args.length; i++) { 547 if (args[i].length() > 0 && args[i].charAt(0) == '@') { 548 String filename = null; 549 if (args[i].length() == 1) { 550 if (i+1 < args.length) 551 filename = args[++i]; 552 } else { 553 filename = args[i].substring(1); 554 } 555 556 if (filename == null) { 557 printError("missing file name argument to @.", null); } else { 559 appendFileContents(filename, argVec); 560 } 561 } else { 562 argVec.add(args[i]); 563 } 564 } 565 final String [] newArgs = (String [])argVec.toArray(new String [0]); 569 return newArgs; 570 } 571 572 577 private void appendFileContents(String filename, ArrayList argVec) { 578 try { 579 FileReader inputFile = new FileReader (filename); 580 try { 581 BufferedReader input = new BufferedReader (inputFile); 582 String s = null; 583 while ((s = input.readLine()) != null) { 584 StringTokenizer parser = new StringTokenizer (s, " \t", false); while (parser.hasMoreElements()) { 586 String token = parser.nextToken(); 587 if (token.length() > 0 && token.charAt(0) == '@') 588 printError("The included file \"" + filename + 590 "\" contains a recursive include. " + "Recursive includes are not supported.", null); if (token.charAt(0) == '#') break; 593 argVec.add(token); 594 } 595 } 596 } 597 catch (IOException ex) { 598 printError("IO exception reading file " + filename + ".", ex); } 600 } 601 catch (FileNotFoundException ex) { 602 printError("file " + filename + " not found.", ex); } 604 } 605 606 607 610 611 private final ByteCodeEnhancer createEnhancer (JDOMetaData jdometadata) 612 throws EnhancerUserException, 613 EnhancerFatalError 614 { 615 616 Properties props = new Properties (); 617 if (this.cmdLineOpts.verbose) 618 { 619 props.put (FilterEnhancer.VERBOSE_LEVEL, FilterEnhancer.VERBOSE_LEVEL_VERBOSE); 620 } 621 622 return new FilterEnhancer (jdometadata, props, this.outMessages, this.outErrors); 623 624 } 626 627 632 633 private final void enhanceInputFiles (Collection filenames) 634 { 635 636 for (Iterator names = filenames.iterator(); names.hasNext ();) 637 { 638 try 639 { 640 String name = (String ) names.next (); 641 int n = name.length (); 642 643 InputStream in = null; 645 if (isClassFileName (name)) 646 { 647 enhanceClassFile (openFileInputStream (name)); 648 } 649 else 650 { 651 if (isZipFileName (name)) 653 { 654 enhanceZipFile (name); } 656 else 658 { 659 enhanceClassFile (openClassInputStream (name)); 660 } 661 } 662 } 663 catch (Throwable ex) 664 { 665 printError (null, ex); 666 } 667 } 668 669 } 671 672 677 678 private final void enhanceClassFile (InputStream in) 679 { 680 681 OutputStream out = null; 682 try 683 { 684 File temp = File.createTempFile ("enhancer", ".class"); 685 out = new BufferedOutputStream (new FileOutputStream (temp)); 686 687 OutputStreamWrapper wrapper = new OutputStreamWrapper (out); 689 boolean enhanced = this.enhancer.enhanceClassFile (in, wrapper); 690 closeOutputStream (out); 691 createOutputFile (enhanced, createClassFileName (wrapper.getClassName ()), temp); 692 } 693 catch (Throwable ex) 694 { 695 printError (null, ex); 696 } 697 finally 698 { 699 closeInputStream (in); 700 closeOutputStream (out); 701 } 702 703 } 705 706 711 712 private final void enhanceZipFile (String filename) 713 { 714 715 ZipInputStream in = null; 716 ZipOutputStream out = null; 717 try 718 { 719 File temp = File.createTempFile ("enhancer", ".zip"); 720 in = new ZipInputStream (new BufferedInputStream (new FileInputStream (new File (filename)))); 721 out = new ZipOutputStream (new BufferedOutputStream (new FileOutputStream (temp))); 722 723 boolean enhanced = ByteCodeEnhancerHelper.enhanceZipFile (this.enhancer, in, out); 725 closeOutputStream (out); 726 out = null; 727 728 createOutputFile (enhanced, new File (filename).getName (), temp); 730 } 731 catch (Throwable ex) 732 { 733 printError (null, ex); 734 } 735 finally 736 { 737 closeOutputStream (out); 738 closeInputStream (in); 739 } 740 741 } 743 744 753 754 private static final InputStream openFileInputStream (String filename) 755 throws FileNotFoundException 756 { 757 758 return new BufferedInputStream (new FileInputStream (new File (filename))); 759 760 } 762 763 774 775 private final InputStream openClassInputStream (String classname) 776 throws IOException , 777 ClassNotFoundException 778 { 779 780 URL url = Main.class.getClassLoader ().getSystemResource (createClassFileName (classname)); 781 if (url == null) 782 { 783 throw new ClassNotFoundException (classname); 784 } 785 return url.openStream (); 786 787 } 789 790 797 798 private static final boolean isClassFileName (String filename) 799 { 800 801 return filename.endsWith (".class"); 802 803 } 805 806 814 815 private static final boolean isZipFileName (String filename) 816 { 817 818 final int n = filename.length (); 819 if (n < 5) 820 { 821 return false; 822 } 823 String ext = filename.substring (n - 4); 824 825 return ext.equalsIgnoreCase (".zip") || ext.equalsIgnoreCase (".jar"); 826 827 } 829 830 838 839 private static final String createClassFileName (String classname) 840 { 841 842 return classname.replace ('.', '/') + ".class"; 843 844 } 846 847 855 856 private final File createZipOutputFile (String zipfilename) 857 { 858 859 return new File (this.cmdLineOpts.destinationDirectory, new File (zipfilename).getName ()); 860 861 } 863 864 874 875 private final void createOutputFile (boolean enhanced, 876 String filename, 877 File temp) 878 throws IOException 879 { 880 881 if (this.cmdLineOpts.noWrite || ( ! enhanced && ! this.cmdLineOpts.forceWrite)) 883 { 884 temp.deleteOnExit (); 885 return; 886 } 887 888 File file = new File (this.cmdLineOpts.destinationDirectory, filename); 889 createPathOfFile (file); 890 file.delete (); boolean renamed = temp.renameTo(file); 893 if (!renamed) { 894 try { 897 DataInputStream dis = 898 new DataInputStream (new FileInputStream (temp)); 899 DataOutputStream dos = 900 new DataOutputStream (new FileOutputStream (file)); 901 int PAGESIZE = 4096; byte data[] = new byte[PAGESIZE]; 903 while (dis.available() > 0) { 904 int numRead = dis.read(data, 0, PAGESIZE); 905 dos.write(data, 0, numRead); 906 } 907 renamed = true; 908 temp.delete (); } catch (IOException ex) { 910 } 912 if (!renamed) { 913 throw new IOException ("Could not rename temp file '" + 914 temp.getAbsolutePath() + 915 "' to '" + file.getAbsolutePath() + "'."); 916 } 917 } 918 } 919 920 921 926 927 private final void closeInputStream (InputStream in) 928 { 929 930 if (in != null) 931 { 932 try 933 { 934 in.close (); 935 } 936 catch (IOException ex) 937 { 938 printError (null, ex); 939 } 940 } 941 942 } 944 945 950 951 private final void closeOutputStream (OutputStream out) 952 { 953 954 if (out != null) 955 { 956 try 957 { 958 out.close (); 959 } 960 catch (IOException ex) 961 { 962 printError (null, ex); 963 } 964 } 965 966 } 968 969 976 977 private static final void createPathOfFile (File file) 978 throws IOException 979 { 980 981 File dir = file.getAbsoluteFile ().getParentFile (); 983 if ( ! dir.exists () && ! dir.mkdirs ()) 984 { 985 throw new IOException ("Error creating directory '" + dir.getAbsolutePath () + "'."); 986 } 987 988 } 990 991 997 998 private final void printError (String msg, 999 Throwable ex) 1000 { 1001 1002 if (msg != null) 1003 { 1004 this.outErrors.println (msg + (ex != null ? ": " + ex : "")); 1005 } 1006 if (ex != null) 1007 { 1008 ex.printStackTrace (this.outErrors); 1009 } 1010 1011 } 1013 1014 1019 1020 private final void printMessage (String msg) 1021 { 1022 1023 this.outMessages.println (msg); 1024 1025 } 1027 1028 1031 public static void usage() { 1032 System.err.println("Usage: main <options> <file name>"); 1034 1040 System.err.println(" { -verbose | -v }"); 1041 System.err.println(" { -force | -f }"); 1042 System.err.println(" { -quiet | -q }"); 1043 1049 1057 1062 System.err.println(" -nowrite"); 1063 System.err.println(" -dest | -d <destination directory>"); 1064 1068 1072 1077 System.err.println(" --jdoProperties | -jp"); 1079 System.err.println(" --timing | -t"); 1080 1081 System.err.println(" @<cmd-arg-file>"); 1082 1083 System.exit (1); 1084 } 1085 1086 1087 1091 1093 private final class CmdLineOptions 1094 { 1095 1096 1097 1100 String destinationDirectory = null; 1101 1102 1103 1106 boolean doTiming = false; 1107 1108 1109 1112 boolean verbose = false; 1113 1114 1115 1118 boolean quiet = false; 1119 1120 1121 1124 boolean forceWrite = false; 1125 1126 1127 1130 boolean noWrite = false; 1131 1132 1133 } 1135 1136} | Popular Tags |