home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 27 / CDROM27.iso / share / wnt / jig / data1.cab / Program_Executable_Files / src / Samples / GetQuotes.java < prev    next >
Encoding:
Java Source  |  1998-08-19  |  12.5 KB  |  343 lines

  1. /*
  2.  * Copyright (c) 1998 S Cubed. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "copyright.html"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * S CUBED MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. S CUBED SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  */
  17.  
  18. package Samples;
  19.  
  20. import java.io.*;
  21. import java.util.*;
  22.  
  23. /**
  24.  * This class provides a utility to make java source i18n compliant.
  25.  *
  26.  * Note the translated file is not ready to compile until the 
  27.  * developer has provided for resource bundle loading and access.
  28.  * For examples, see the Java Internationalization documentation.
  29.  */
  30.  
  31. public class GetQuotes  {
  32. static int quoteCount = 0;
  33. static int keyDifferentiator=0;
  34. static int MaxQuote=4096;
  35. static int excludeCount = 0;
  36. static String[] quotes=new String[MaxQuote];
  37. static String[] keys=new String[MaxQuote];
  38. static String[] excludes=new String[MaxQuote];
  39. static String outputDirectory="";
  40. static String resBundleName="resbun";
  41. /**
  42.  * Create an instance of GetQuotes.
  43.  * Load files and initiate the parsing/translation operation.
  44.  *
  45.  * @param name the file or directory name
  46.  * @param output a flag indicating the translated file is to be sent to stdout
  47.  */
  48. GetQuotes  (String name,boolean output) {
  49.  
  50.     StreamTokenizer tokenStream=null;
  51.     FileOutputStream fos=null;
  52.     File f = new File(name);
  53.     if (f.isDirectory()) {
  54.         String[] fileList = f.list(new ExtensionFilter(".java"));
  55.         for (int i=0;i<fileList.length;i++) {
  56.             //System.out.println("\nFILE: "+fileList[i]);
  57.             try {
  58.                 tokenStream = new StreamTokenizer(
  59.                 new FileInputStream(name+System.getProperty("file.separator")+fileList[i]));
  60.                 } catch (FileNotFoundException ex) {
  61.                 tokenStream = null;
  62.                 //                System.out.println("File not found, "+ex);
  63.                 }
  64.             if (tokenStream != null) { 
  65.                 try {
  66.                     if (outputDirectory != null)
  67.                     fos = new FileOutputStream(outputDirectory+System.getProperty("file.separator")+fileList[i]);
  68.                     } catch (IOException e) {
  69.                     System.out.println("File not opened, "+e);
  70.                     }
  71.                 parseStream(output,tokenStream,fos);
  72.                 try {
  73.                     if (fos != null) fos.close();
  74.                     } catch (IOException e2) {}
  75.                 fos = null;
  76.                 }
  77.             }
  78.         }
  79.     else {
  80.  
  81.         try {
  82.             tokenStream = new StreamTokenizer(new FileInputStream(name));
  83.             } catch (FileNotFoundException ex) {
  84.             System.out.println("File not found, "+ex);
  85.             }
  86.         parseStream(output,tokenStream,null);
  87.         }
  88.     }
  89. /**
  90.  * Runs GetQuotes accepting command args and performing GetQuotes invocation.
  91.  *
  92.  * Examples:
  93.  * To generate a table to stdout, with no translated file, <pre>
  94.  * Samples.GetQuotes ..\Samples\BuildAccessorWindow.java -h"American English" -t 
  95.  * </pre>
  96.  * To generate a translation to stdout, <pre>
  97.  * Samples.GetQuotes ..\Samples\BuildAccessorWindow.java -bMyResources -o 
  98.  * </pre>
  99.  * To generate translated files from the Samples directory to Samples/I18n, 
  100.  * with a locale file captured in a file from stdout, using a string 
  101.  * excludes file and a specific resource bundle name, <pre>
  102.  * Samples.GetQuotes ..\Samples -h"American English" -xsamplesExclude.txt -t -d..\Samples\I18n -bMyResources > locale_en_US.properties
  103.  * </pre>
  104.  *
  105.  * @param args list of command line arguments
  106.  */
  107. public static void main (String args[]) {
  108.  
  109.     if (args.length <1) {
  110.         System.out.println("Usage: GetQuotes filename|directory [-bdhotx]");
  111.         System.out.println(" -o send the translated source to stdout");
  112.         System.out.println(" -b name of the resource bundle variable or class (dflt: resbun)");
  113.         System.out.println(" -d the translation destination directory (when a source dir is 1st arg)");
  114.         System.out.println(" -h the header string to write in the locale file");
  115.         System.out.println(" -t send the locale resources to stdout");
  116.         System.out.println(" -x full name of the file of strings to exclude");
  117.         System.exit(1);
  118.         }
  119.     String header="Locale file";
  120.     boolean output= false,table = false;
  121.     for (int i=1;i<args.length;i++) {
  122.         if (args[i].startsWith("-o")) output = true;
  123.         else if (args[i].startsWith("-t")) table = true;
  124.     else if (args[i].startsWith("-h")) header = args[i].substring(2);
  125.     else if (args[i].startsWith("-b")) resBundleName = args[i].substring(2);
  126.     else if (args[i].startsWith("-d")) outputDirectory = args[i].substring(2);
  127.     else if (args[i].startsWith("-x")) loadExcludes(args[i].substring(2));
  128.         }
  129.     GetQuotes gq = new GetQuotes(args[0],output);
  130.  
  131.     if (table) {
  132.         System.out.println("# "+header);
  133.         System.out.println("# "+new Date());
  134.         for (int i=0;i<gq.quoteCount;i++)
  135.         System.out.println (gq.keys[i]+"="+gq.quotes[i]);
  136.         }
  137.  
  138.     System.exit(1);
  139.     }
  140. /**
  141.  * Parses the source code substituting keys for quoted strings.
  142.  *
  143.  * @param outputFlag if true send parsed and translated text to stdout
  144.  * @param stis a StreamTokenizer to handle the source code parsing
  145.  * @param fos an output stream to write parsed source and translations.
  146.  */
  147. void parseStream  (boolean outputFlag,StreamTokenizer stis,FileOutputStream fos) {
  148.  
  149.  
  150.     stis.resetSyntax();
  151.     stis.slashStarComments(false);
  152.     stis.slashSlashComments(false);
  153.     stis.quoteChar('"');
  154.  
  155.     try {
  156.         while (stis.nextToken() != StreamTokenizer.TT_EOF) {
  157.  
  158.             switch ((char) stis.ttype) {
  159.  
  160.                 case (char)'"':
  161.                     String temp = getSub(stis.sval);
  162.                     if (outputFlag) System.out.print(temp);
  163.                     if (fos != null) fos.write(temp.getBytes());
  164.                 break;
  165.  
  166.                 default:
  167.                 if (outputFlag) System.out.print((char)stis.ttype);
  168.                 if (fos != null) fos.write(stis.ttype);
  169.                 }
  170.             }
  171.         } catch (IOException ex) {
  172.         }
  173.     }
  174. /**
  175.  * Gets the substition key string for the original string.  If the
  176.  * string does not exist in the database of strings, store it and 
  177.  * create a key for it.  If the original quote is found in a list of
  178.  * quotes to exclude the original quote is returned.  Translated
  179.  * keys are returned with the resource bundle accessor method syntax.
  180.  *
  181.  * @param originalQuote the content of a quoted string found in the source code
  182.  * @return if translated, the key to the string, else the original string
  183.  */
  184. String getSub  (String originalQuote) {
  185.     String quote = originalQuote;
  186.     int i;
  187.  
  188.     // handle empty strings
  189.     if (originalQuote.length() == 0) return "\"\"";
  190.  
  191.     // first remove and set aside any trailing sourcecode whitespace
  192.     // suffix
  193.     for (i=quote.length()-1;
  194.     i>=0 && Character.isWhitespace(quote.charAt(i));
  195.     i--);
  196.  
  197.     String suffix =  quote.substring(++i,quote.length());
  198.     quote = quote.substring(0,i);
  199.  
  200.     // prefix
  201.     for (i=0;
  202.     i<quote.length() && Character.isWhitespace(quote.charAt(i));
  203.     i++);
  204.  
  205.     String prefix =  quote.substring(0,i);
  206.     quote = quote.substring(i,quote.length());
  207.  
  208.     // look for quote in db, if not there add it
  209.     if (quote.length() > 0) {
  210.         String resQuote = restored(quote);
  211.         if (isExclude(resQuote)) return "\""+restored(originalQuote)+"\"";
  212.         else {
  213.             for (i=0;i<quoteCount;i++)
  214.             if (quotes[i].equals(resQuote)) break;
  215.             if (i == quoteCount) {
  216.                 keys[quoteCount] = makeKey(quote);
  217.                 quotes[quoteCount++] = quote = resQuote;
  218.                 }
  219.             }
  220.         }
  221.  
  222.     // create source ready suffix
  223.     String suffixCode = new String ("");
  224.     for (int j=0;j<suffix.length();j++) switch (suffix.charAt(j)) {
  225.         case '"' : suffixCode += "\\\""; break;
  226.         case '\n' : suffixCode += "\\n"; break;
  227.         case '\t' : suffixCode += "\\t"; break;
  228.         case '\r' : suffixCode += "\\r"; break;
  229.         case ' ' : suffixCode += " "; break;
  230.         default :;
  231.         }
  232.     // create source ready prefix
  233.     String prefixCode = new String ("");
  234.     for (int j=0;j<prefix.length();j++) switch (prefix.charAt(j)) {
  235.         case '"' : prefixCode += "\\\""; break;
  236.         case '\n' : prefixCode += "\\n"; break;
  237.         case '\t' : prefixCode += "\\t"; break;
  238.         case '\r' : prefixCode += "\\r"; break;
  239.         case ' ' : prefixCode += " "; break;
  240.         default :;
  241.         }
  242.  
  243.     String resultString = new String();
  244.     if (prefixCode.length() > 0) resultString += "\""+prefixCode+"\"";
  245.     if (quote.length() > 0) {
  246.         if (resultString.length() > 0) resultString += "+";
  247.         resultString += resBundleName+".getString(\""+keys[i]+"\")";
  248.         }
  249.     if (suffixCode.length() > 0) {
  250.         if (resultString.length() > 0) resultString += "+";
  251.         resultString += "\""+suffixCode+"\"";
  252.         }
  253.     return resultString;
  254.     }
  255. /**
  256.  * Turns a quote string into an acceptable key.
  257.  * The key and the quote are ultimately stored in the locale file.
  258.  * Keys are generated by taking the first words of the quote, special
  259.  * characters are excluded, capitalizing the words, concatenating 
  260.  * the words together, truncating the words at a certain length, then
  261.  * adding a number to make the key unique if necessary.
  262.  * If a quote does not have the requisite words to form a key, a special
  263.  * key is generated for the quote.
  264.  * 
  265.  * @param quote the quote taken from the source code
  266.  * @return the new key for the quote
  267.  */
  268. String makeKey  (String quote) {
  269.     String key= new String();
  270.     StringTokenizer st = new StringTokenizer(quote," \t\n!@#$%^&*()_-+={}|[]:;'<>,.?/~`",false);
  271.     while (st.hasMoreTokens()) {
  272.     String temp = st.nextToken();
  273.     if (temp.length() > 1)
  274.     temp = temp.substring(0,1).toUpperCase() + temp.substring(1,temp.length());
  275.         key += temp;
  276.         }
  277.     if (key.length()==0) key = "GenKey";
  278.     int keylen = 10;
  279.     boolean keyDone=false;
  280.     String tryKey=null;
  281.     while (!keyDone) {
  282.         int i;
  283.     tryKey = key.substring(0,key.length() > keylen ? keylen : key.length());
  284.         for (i=0;i<quoteCount;i++)
  285.         if (keys[i].equals(tryKey)) break;
  286.         if (i == quoteCount) keyDone = true;
  287.     keylen++;
  288.     if (keylen== 16) {
  289. //        System.out.println("ERROR, max keylen");
  290.         return (tryKey+(keyDifferentiator++));
  291.         }
  292.         }    
  293.     return tryKey;
  294.     }
  295. /**
  296.  * Loads the file of excluded strings.
  297.  *
  298.  * @param filename the name of the file containing the excluded strings.
  299.  */
  300. static void loadExcludes  (String filename) {
  301.     try {
  302.         BufferedReader fis = new BufferedReader(new FileReader(filename));
  303.         for (excludeCount=0;(excludes[excludeCount]=fis.readLine()) != null; excludeCount++);
  304.         } catch (FileNotFoundException e) {
  305.         return;
  306.         } catch (IOException e2) {
  307.         return;
  308.         }
  309.     }
  310. /**
  311.  * Checks if the string is to be excluded from translation.
  312.  *
  313.  * @param quote a quoted string from the source code
  314.  * @return true if found on the excludes list else false
  315.  */
  316. boolean isExclude  (String quote) {
  317.     if (excludeCount == 0) return false;
  318.     for (int i=0;i<excludeCount;i++)
  319.         if (quote.equals(excludes[i])) return true;
  320.     return false;
  321.     }
  322. /**
  323.  * Translates special control characters into escape character sequences.
  324.  * 
  325.  * @param quote a string possibly containing special control characters
  326.  * @return the quote with any control characters converted to escape sequences
  327.  */
  328. private String restored  (String quote) {
  329.     byte[] b = quote.getBytes();
  330.     StringWriter sw = new StringWriter();
  331.  
  332.     for (int j=0;j<b.length;j++) switch (b[j]) {
  333.         case '"' : sw.write("\\\""); break;
  334.         case '\n' : sw.write("\\n"); break;
  335.         case '\t' : sw.write("\\t"); break;
  336.         case '\r' : sw.write("\\r"); break;
  337.         case ' ' : sw.write(' '); break;
  338.         default :    sw.write(b[j]);
  339.         }
  340. return sw.toString();
  341.     }
  342. }
  343.