home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-08-19 | 12.5 KB | 343 lines |
- /*
- * Copyright (c) 1998 S Cubed. All Rights Reserved.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for NON-COMMERCIAL purposes and without
- * fee is hereby granted provided that this copyright notice
- * appears in all copies. Please refer to the file "copyright.html"
- * for further important copyright and licensing information.
- *
- * S CUBED MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
- * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. S CUBED SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
- */
-
- package Samples;
-
- import java.io.*;
- import java.util.*;
-
- /**
- * This class provides a utility to make java source i18n compliant.
- *
- * Note the translated file is not ready to compile until the
- * developer has provided for resource bundle loading and access.
- * For examples, see the Java Internationalization documentation.
- */
-
- public class GetQuotes {
- static int quoteCount = 0;
- static int keyDifferentiator=0;
- static int MaxQuote=4096;
- static int excludeCount = 0;
- static String[] quotes=new String[MaxQuote];
- static String[] keys=new String[MaxQuote];
- static String[] excludes=new String[MaxQuote];
- static String outputDirectory="";
- static String resBundleName="resbun";
- /**
- * Create an instance of GetQuotes.
- * Load files and initiate the parsing/translation operation.
- *
- * @param name the file or directory name
- * @param output a flag indicating the translated file is to be sent to stdout
- */
- GetQuotes (String name,boolean output) {
-
- StreamTokenizer tokenStream=null;
- FileOutputStream fos=null;
- File f = new File(name);
- if (f.isDirectory()) {
- String[] fileList = f.list(new ExtensionFilter(".java"));
- for (int i=0;i<fileList.length;i++) {
- //System.out.println("\nFILE: "+fileList[i]);
- try {
- tokenStream = new StreamTokenizer(
- new FileInputStream(name+System.getProperty("file.separator")+fileList[i]));
- } catch (FileNotFoundException ex) {
- tokenStream = null;
- // System.out.println("File not found, "+ex);
- }
- if (tokenStream != null) {
- try {
- if (outputDirectory != null)
- fos = new FileOutputStream(outputDirectory+System.getProperty("file.separator")+fileList[i]);
- } catch (IOException e) {
- System.out.println("File not opened, "+e);
- }
- parseStream(output,tokenStream,fos);
- try {
- if (fos != null) fos.close();
- } catch (IOException e2) {}
- fos = null;
- }
- }
- }
- else {
-
- try {
- tokenStream = new StreamTokenizer(new FileInputStream(name));
- } catch (FileNotFoundException ex) {
- System.out.println("File not found, "+ex);
- }
- parseStream(output,tokenStream,null);
- }
- }
- /**
- * Runs GetQuotes accepting command args and performing GetQuotes invocation.
- *
- * Examples:
- * To generate a table to stdout, with no translated file, <pre>
- * Samples.GetQuotes ..\Samples\BuildAccessorWindow.java -h"American English" -t
- * </pre>
- * To generate a translation to stdout, <pre>
- * Samples.GetQuotes ..\Samples\BuildAccessorWindow.java -bMyResources -o
- * </pre>
- * To generate translated files from the Samples directory to Samples/I18n,
- * with a locale file captured in a file from stdout, using a string
- * excludes file and a specific resource bundle name, <pre>
- * Samples.GetQuotes ..\Samples -h"American English" -xsamplesExclude.txt -t -d..\Samples\I18n -bMyResources > locale_en_US.properties
- * </pre>
- *
- * @param args list of command line arguments
- */
- public static void main (String args[]) {
-
- if (args.length <1) {
- System.out.println("Usage: GetQuotes filename|directory [-bdhotx]");
- System.out.println(" -o send the translated source to stdout");
- System.out.println(" -b name of the resource bundle variable or class (dflt: resbun)");
- System.out.println(" -d the translation destination directory (when a source dir is 1st arg)");
- System.out.println(" -h the header string to write in the locale file");
- System.out.println(" -t send the locale resources to stdout");
- System.out.println(" -x full name of the file of strings to exclude");
- System.exit(1);
- }
- String header="Locale file";
- boolean output= false,table = false;
- for (int i=1;i<args.length;i++) {
- if (args[i].startsWith("-o")) output = true;
- else if (args[i].startsWith("-t")) table = true;
- else if (args[i].startsWith("-h")) header = args[i].substring(2);
- else if (args[i].startsWith("-b")) resBundleName = args[i].substring(2);
- else if (args[i].startsWith("-d")) outputDirectory = args[i].substring(2);
- else if (args[i].startsWith("-x")) loadExcludes(args[i].substring(2));
- }
- GetQuotes gq = new GetQuotes(args[0],output);
-
- if (table) {
- System.out.println("# "+header);
- System.out.println("# "+new Date());
- for (int i=0;i<gq.quoteCount;i++)
- System.out.println (gq.keys[i]+"="+gq.quotes[i]);
- }
-
- System.exit(1);
- }
- /**
- * Parses the source code substituting keys for quoted strings.
- *
- * @param outputFlag if true send parsed and translated text to stdout
- * @param stis a StreamTokenizer to handle the source code parsing
- * @param fos an output stream to write parsed source and translations.
- */
- void parseStream (boolean outputFlag,StreamTokenizer stis,FileOutputStream fos) {
-
-
- stis.resetSyntax();
- stis.slashStarComments(false);
- stis.slashSlashComments(false);
- stis.quoteChar('"');
-
- try {
- while (stis.nextToken() != StreamTokenizer.TT_EOF) {
-
- switch ((char) stis.ttype) {
-
- case (char)'"':
- String temp = getSub(stis.sval);
- if (outputFlag) System.out.print(temp);
- if (fos != null) fos.write(temp.getBytes());
- break;
-
- default:
- if (outputFlag) System.out.print((char)stis.ttype);
- if (fos != null) fos.write(stis.ttype);
- }
- }
- } catch (IOException ex) {
- }
- }
- /**
- * Gets the substition key string for the original string. If the
- * string does not exist in the database of strings, store it and
- * create a key for it. If the original quote is found in a list of
- * quotes to exclude the original quote is returned. Translated
- * keys are returned with the resource bundle accessor method syntax.
- *
- * @param originalQuote the content of a quoted string found in the source code
- * @return if translated, the key to the string, else the original string
- */
- String getSub (String originalQuote) {
- String quote = originalQuote;
- int i;
-
- // handle empty strings
- if (originalQuote.length() == 0) return "\"\"";
-
- // first remove and set aside any trailing sourcecode whitespace
- // suffix
- for (i=quote.length()-1;
- i>=0 && Character.isWhitespace(quote.charAt(i));
- i--);
-
- String suffix = quote.substring(++i,quote.length());
- quote = quote.substring(0,i);
-
- // prefix
- for (i=0;
- i<quote.length() && Character.isWhitespace(quote.charAt(i));
- i++);
-
- String prefix = quote.substring(0,i);
- quote = quote.substring(i,quote.length());
-
- // look for quote in db, if not there add it
- if (quote.length() > 0) {
- String resQuote = restored(quote);
- if (isExclude(resQuote)) return "\""+restored(originalQuote)+"\"";
- else {
- for (i=0;i<quoteCount;i++)
- if (quotes[i].equals(resQuote)) break;
- if (i == quoteCount) {
- keys[quoteCount] = makeKey(quote);
- quotes[quoteCount++] = quote = resQuote;
- }
- }
- }
-
- // create source ready suffix
- String suffixCode = new String ("");
- for (int j=0;j<suffix.length();j++) switch (suffix.charAt(j)) {
- case '"' : suffixCode += "\\\""; break;
- case '\n' : suffixCode += "\\n"; break;
- case '\t' : suffixCode += "\\t"; break;
- case '\r' : suffixCode += "\\r"; break;
- case ' ' : suffixCode += " "; break;
- default :;
- }
- // create source ready prefix
- String prefixCode = new String ("");
- for (int j=0;j<prefix.length();j++) switch (prefix.charAt(j)) {
- case '"' : prefixCode += "\\\""; break;
- case '\n' : prefixCode += "\\n"; break;
- case '\t' : prefixCode += "\\t"; break;
- case '\r' : prefixCode += "\\r"; break;
- case ' ' : prefixCode += " "; break;
- default :;
- }
-
- String resultString = new String();
- if (prefixCode.length() > 0) resultString += "\""+prefixCode+"\"";
- if (quote.length() > 0) {
- if (resultString.length() > 0) resultString += "+";
- resultString += resBundleName+".getString(\""+keys[i]+"\")";
- }
- if (suffixCode.length() > 0) {
- if (resultString.length() > 0) resultString += "+";
- resultString += "\""+suffixCode+"\"";
- }
- return resultString;
- }
- /**
- * Turns a quote string into an acceptable key.
- * The key and the quote are ultimately stored in the locale file.
- * Keys are generated by taking the first words of the quote, special
- * characters are excluded, capitalizing the words, concatenating
- * the words together, truncating the words at a certain length, then
- * adding a number to make the key unique if necessary.
- * If a quote does not have the requisite words to form a key, a special
- * key is generated for the quote.
- *
- * @param quote the quote taken from the source code
- * @return the new key for the quote
- */
- String makeKey (String quote) {
- String key= new String();
- StringTokenizer st = new StringTokenizer(quote," \t\n!@#$%^&*()_-+={}|[]:;'<>,.?/~`",false);
- while (st.hasMoreTokens()) {
- String temp = st.nextToken();
- if (temp.length() > 1)
- temp = temp.substring(0,1).toUpperCase() + temp.substring(1,temp.length());
- key += temp;
- }
- if (key.length()==0) key = "GenKey";
- int keylen = 10;
- boolean keyDone=false;
- String tryKey=null;
- while (!keyDone) {
- int i;
- tryKey = key.substring(0,key.length() > keylen ? keylen : key.length());
- for (i=0;i<quoteCount;i++)
- if (keys[i].equals(tryKey)) break;
- if (i == quoteCount) keyDone = true;
- keylen++;
- if (keylen== 16) {
- // System.out.println("ERROR, max keylen");
- return (tryKey+(keyDifferentiator++));
- }
- }
- return tryKey;
- }
- /**
- * Loads the file of excluded strings.
- *
- * @param filename the name of the file containing the excluded strings.
- */
- static void loadExcludes (String filename) {
- try {
- BufferedReader fis = new BufferedReader(new FileReader(filename));
- for (excludeCount=0;(excludes[excludeCount]=fis.readLine()) != null; excludeCount++);
- } catch (FileNotFoundException e) {
- return;
- } catch (IOException e2) {
- return;
- }
- }
- /**
- * Checks if the string is to be excluded from translation.
- *
- * @param quote a quoted string from the source code
- * @return true if found on the excludes list else false
- */
- boolean isExclude (String quote) {
- if (excludeCount == 0) return false;
- for (int i=0;i<excludeCount;i++)
- if (quote.equals(excludes[i])) return true;
- return false;
- }
- /**
- * Translates special control characters into escape character sequences.
- *
- * @param quote a string possibly containing special control characters
- * @return the quote with any control characters converted to escape sequences
- */
- private String restored (String quote) {
- byte[] b = quote.getBytes();
- StringWriter sw = new StringWriter();
-
- for (int j=0;j<b.length;j++) switch (b[j]) {
- case '"' : sw.write("\\\""); break;
- case '\n' : sw.write("\\n"); break;
- case '\t' : sw.write("\\t"); break;
- case '\r' : sw.write("\\r"); break;
- case ' ' : sw.write(' '); break;
- default : sw.write(b[j]);
- }
- return sw.toString();
- }
- }
-