Hi,

I wrote a silly translation check program (LocCompare.java) that flags
possible trouble between the current english locale files and possible
new translations.
You'd have to build the class, add it to the classpath, put the
possible new translations files in two (one top, and a subdir for the
drda ones) directories and run the class like so:

- java  -Dderbysvntop=<top of trunk or source> -Dtranslations=<temp
location topdir> LocCompare pt_BR > checkBR.out 2>&1

I used the current Brazilian translations because they're the most up
to date...I copied them to the temporary location.
I'm attaching the output (with the actual location edited out manually).

There's little actual failures I found, but still...
Does this look like a useful tool to be added to derby?
If so, where should it live?

Thx,
Myrna
/*
 * Created on Oct 17, 2006
 *
 */

import java.io.*;
import java.util.ArrayList;

/**
 * @author myrna
 *
 */
public class LocCompare {

    private static String USAGE=
        "USAGE: \n java \n  [-Dderbysvntop=<svntop>] [-Dtranslations=<newloc>] 
LocCompare <territories>]\n" +
        "  where \n" +
        "     svntop      = top of derby svn tree for branch or trunk \n" +
        "                   default is current dir is the top\n" +
        "     newloc      = location where the translated files are 
temporarily\n" +
        "                   default is currentdir\n" +
        "                   drda locale files are expected in a subdir 
'drda'\n" +
        "     territories = one translated territories, or 'all' \n" +
        "                   where all means: \n" +
        "                      
{cs,de_DE,es,fr,hu,it,ja_JP,ko_KR,pl,pt_BR,ru,zh_CN,zh_TW}\n" +
        "\n" +
        "   you can also pass -Dtvtdebug=true to see more comments.";
        
        public static void main(String[] args) {
                // some args checking and usage.
                String curdir = System.getProperty("user.home");
                String svntop = curdir;
                String locnewlocfiles = curdir;
                String languages[] = 
{"cs","de_DE","es","fr","hu","it","ja_JP","ko_KR","pl","pt_BR","ru","zh_CN","zh_TW"};
                if (args.length == 0) // no arguments, will assume currentdir 
for loc files
                        curdir = System.getProperty("user.home");
                else if ((args.length >2) || (args[0].equals("?") || 
(args[0].startsWith("-h"))))
                {
                        logMsg(USAGE);
                        return;
                }
                else if ((args.length==1) && (!args[0].equals("all")))
                {
                        languages = new String[1];
                        languages[0] = args[0];
                }
                
                if (System.getProperty("derbysvntop") == null )
                        logMsg("don't know where to start from, assuming 
current dir");
                else
                        svntop = System.getProperty("derbysvntop");
                
                if (System.getProperty("translations") == null )
                        logMsg("don't know where to start from, assuming 
current dir");
                else
                        locnewlocfiles = System.getProperty("translations");
                
                // making assumptions about tha paths and filenames
                String ext = ".properties";
                String[] typefiles = 
{"messages_","sysinfoMessages_","toolsmessages_"};
                String[] drdatypefiles = {"messages_","servlet_"};
                
                String englishPath = svntop + 
"/java/engine/org/apache/derby/loc/";
                String english = "en";
                String englishDrdaPath = svntop + 
"/java/drda/org/apache/derby/loc/drda/";
                String englishToolsPath = svntop + 
"/java/tools/org/apache/derby/loc/";
                
                String forLangPath = locnewlocfiles + "/";
                String drdaSubPath = locnewlocfiles + "/drda/";
                
                String EnglishFileName;
                String ForeignFileName;

                // first find the apprioriate embedded messages
                for (int i=0; i< typefiles.length; i++)
                {
                        if (( typefiles[i].equals("sysinfoMessages_")) || 
(typefiles[i].equals("toolsmessages_")))
                                EnglishFileName=englishToolsPath + 
typefiles[i].substring(0,(typefiles[i].length()-1)) + ext;
                        else    
                                EnglishFileName=englishPath + typefiles[i] + 
english + ext;
                        for (int j=0; j < languages.length; j++)
                        {
                                ForeignFileName=forLangPath + typefiles[i] + 
languages[j] + ext;
                                logMsg(" 
********************************************* ");
                                logMsg(" 
********************************************* ");
                                logMsg("Now comparing " + EnglishFileName +
                                                " and " + ForeignFileName);
                                compare(EnglishFileName, ForeignFileName);
                        }
                }
                
                // now compare the drda messages
                for (int i=0; i< drdatypefiles.length; i++)
                {
                        EnglishFileName=englishDrdaPath + drdatypefiles[i] + 
english + ext;
                        for (int j=0; j < languages.length; j++)
                        {
                                ForeignFileName=drdaSubPath + drdatypefiles[i] 
+ languages[j] + ext;
                                logMsg(" 
********************************************* ");
                                logMsg(" 
********************************************* ");
                                logMsg("now comparing " + EnglishFileName +
                                                " and " + ForeignFileName);
                                compare(EnglishFileName, ForeignFileName);
                        }
                }
        }
        
        public static void compare(String englishFileName, String 
foreignFileName){
                String openBrace="{";
                String closeBrace="}";
                String apostrophe="'";

                try {
                        BufferedReader englishR = new BufferedReader(
                                        new InputStreamReader(new 
FileInputStream(englishFileName), "UTF8"));
                        BufferedReader foreignR = new BufferedReader(
                                        new InputStreamReader(new 
FileInputStream(foreignFileName), "UTF8"));
                        
                        int i=0;
                        String englishStr;
                        String foreignStr;
                        
                        while ((englishStr = englishR.readLine())!=null)
                        {
                                i++;
                                // first position English on a message
                                // note that this means we're only checking the 
first
                                // line of each message...
                                if ((englishStr.indexOf("=") < 0) ||
                                        (englishStr.indexOf("#")>=0)   || 
                                        (englishStr.indexOf("user=usr")>0)) // 
may be url syntax
                                        continue;
                                String englishError = "";
                                String foreignError = "";
                                        
                                englishError = 
englishStr.substring(0,englishStr.indexOf("="));                         
                                // position foreign str on same message
                                foreignStr = foreignR.readLine();
                                if (foreignStr == null)
                                {
                                        // oops, odd, we're not getting 
anything.
                                        logMsg(" MAJOR FAILURE, can't find 
foreign text");
                                        return;
                                }
                                else if ((foreignStr != null) &&
                                                 (foreignStr.indexOf("=")>0) &&
                                                 (foreignStr.indexOf("#")<0) &&
                                                 
(!foreignStr.trim().equals("")))
                                        foreignError = 
foreignStr.substring(0,foreignStr.indexOf("="));
                                else 
                                        while ((foreignStr.indexOf("=")<0) ||
                                                  (foreignStr.indexOf("#")>=0) 
||
                                                  
(foreignStr.trim().equals("")))
                                        {
                                                foreignStr=foreignR.readLine();
                                        }
                                
                                foreignError = 
foreignStr.substring(0,foreignStr.indexOf("="));
                                                                        
                                // ok theoretically we are now at the same place
                                // just make sure to position the foreignStr at 
the same message
                                chatterMsg("\tforeignStr is now: " + 
foreignStr);
                                chatterMsg("\tenglishStr is now: " + 
englishStr);
                                chatterMsg("\tforeignError is now: " + 
foreignError);
                                chatterMsg("\tenglishError is now: " + 
englishError);
                                
                                // first check that the substring up to the '=' 
is the same for both.
                                // else, search through foreign file until we 
find the right
                                // message
                                // give error if the message is not found in 
the foreign file
                                // only strings with = can be compared, and not 
user=usr (dblook usage)
                                if (!englishError.equals(foreignError))
                                {
                                        chatterMsg("\t WARNING - error number 
not the same; " + englishError);
                                        chatterMsg("\t   attempting to reset 
foreign file");
                                        foreignR = new BufferedReader(
                                                        new 
InputStreamReader(new FileInputStream(foreignFileName), "UTF8"));   
                                        while ( (foreignStr != null) && 
(foreignStr.indexOf(englishError)<0))
                                        {
                                                foreignStr = 
foreignR.readLine();
                                                chatterMsg
                                                        ("\t\tsearching for 
Error " + englishError + 
                                                                        ", 
ForeignString :" + foreignStr);
                                        }
                                        if (foreignStr == null)
                                        {
                                                // we must not have found the 
message
                                                logMsg("\t FAILURE!! Message 
not found in foreign file: " + englishError);
                                                continue;       
                                        }
                                        
                                // theoretically, we should now be at the same 
error again.
                                }
                                else                            
                                        chatterMsg("\tMessage: " + englishError 
+ "(en), found match") ;
                                // just for fun, compare occurrences of some 
unusual characters:                                
                                int count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "%", 
englishError);
                                // let's not check for , it is a language 
specific construct
                                //count = countAndCompareCountCharacter(
                                //              englishStr, foreignStr, ",", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, ";", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, ":", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "_", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "=", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "(", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, ")", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "+", 
englishError);
                                // let's not check for -, it is a language 
specific construct
                                //count = countAndCompareCountCharacter(
                                //              englishStr, foreignStr, "-", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "/", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "]", 
englishError);
                                count = countAndCompareCountCharacter(
                                                englishStr, foreignStr, "[", 
englishError);
                                
                                // check to see if the errorstring has a {
                                int countOpen = countAndCompareCountCharacter(
                                                englishStr, foreignStr, 
openBrace, englishError);
                                // then check to see if the errorstring has a } 
                                int countClose = countAndCompareCountCharacter(
                                                englishStr, foreignStr, 
closeBrace, englishError);
                                if ((countOpen <0) || (countClose <0))
                                {
                                        // we have a mismatch between the 
languages should already have seen an error
                                        continue;
                                }                       
                                if (countOpen != countClose)
                                {       
                                        logMsg("\t FAILURE!!! - unmatched 
braces in error " + englishError);
                                        continue;
                                }
                                // now check that the parameter numbers 
encircled by the braces are matching
                                compareParameterSequenceNumbers(englishStr, 
foreignStr, countOpen, englishError);

                                // now, if we do not have replacements, in 
theory there is no need for
                                // double quotes. So, check for apostropes
                                if ((countOpen == 0) || (countClose == 0))
                                {
                                        chatterMsg("\t\tin English file, ");
                                        lookAtSingleQuotes(englishStr, 
apostrophe, englishError, englishFileName);
                                        chatterMsg("\t\tin foreign file, ");
                                        lookAtSingleQuotes(foreignStr, 
apostrophe, foreignError, foreignFileName);
                                }
                                else if ((countOpen == countClose) && 
(countOpen > 0))
                                {
                                        // if we have replacements, all 
apostrophes *must*
                                        // get doubled.
                                        if ((englishStr.indexOf(apostrophe) < 
0) && (foreignStr.indexOf(apostrophe) < 0))
                                                continue;
                                        else
                                        {
                                                chatterMsg("\t\tin English 
file, ");
                                                lookAtDoubleQuotes(englishStr, 
apostrophe, englishError, englishFileName);
                                                chatterMsg("\t\tin foreign 
file, ");
                                                lookAtDoubleQuotes(foreignStr, 
apostrophe, foreignError, foreignFileName);
                                        }
                                }
                                // last automated check is to find strings
                                // with all capitals and compare....
                                compareUpperCaseStrings(englishStr, foreignStr, 
englishError, foreignFileName);
                        }
                } catch (UnsupportedEncodingException e) {
                } catch (IOException e) {
                }
        }
        
        /**
         * 
         * @param englishStr
         * @param foreignStr
         * @param Character
         * @return 0 if the character does not occur at all
         *         -1 if there is a difference between English and translation
         *         #>0 indicating the number of occurrences of the character
         */
        public static int countAndCompareCountCharacter(
                        String englishStr, String foreignStr, String Character, 
String englishError)
        {
                if (englishStr.indexOf(Character)< 0)
                        return 0;
                else { // (if character exists)
                        //then compare the number of occurrences per line
                        int noCharE=0;
                        int noCharF=0;
                        noCharE = countCharacter(englishStr, Character);
                        noCharF = countCharacter(foreignStr, Character);
                        if (noCharE!=noCharF)
                        {
                                logMsg("\t WARNING - not the same number of the 
character " + Character + " for error: " + englishError);
                                return -1;
                        }
                        else
                        {       
                                chatterMsg("\t\tsame number of the character " 
+ Character + ", namely, :" + noCharE + " for error: " + englishError);
                                return noCharE;
                        }
                }
        }
        
        /**
         * 
         * @param englishStr
         * @param foreignStr
         * @param Character
         * @return 0 if the character does not occur at all
         *         -1 if there is a difference between English and translation
         *         #>0 indicating the number of occurrences of the character
         */
        public static int countCharacter(String Str, String Character)
        {
                if (Str.indexOf(Character)< 0)
                        return 0;
                else { // (if character exists)
                //then compare the number of occurrences per line
                        String tmpstr = Str;
                        int noChar=0;
                        for (int k=0; k<Str.length() ; k++){
                                if (tmpstr.indexOf(Character) >= 0)
                                        noChar++;
                                        tmpstr = 
tmpstr.substring(tmpstr.indexOf(Character)+1);
                        }
                        return noChar;
                }
        }
        
        public static void compareParameterSequenceNumbers(
                        String englishStr, String foreignStr, int 
NumberOfParameters, String englishError)
        {
                for ( int i=0 ; i < NumberOfParameters; i++)
                {

                        //chatterMsg("\t\tcompare parameter seq numbers, 
englishStr is now: " + englishStr);
                        //chatterMsg("\t\tcompare parameter seq numbers, 
foreignStr is now: " + foreignStr);
                        int eindex1 = englishStr.indexOf("{");
                        int findex1 = foreignStr.indexOf("{");
                        int eindex2 = englishStr.indexOf("}");
                        int findex2 = foreignStr.indexOf("}");
                        String englishSubStr1 = englishStr.substring(eindex1+1, 
eindex2);
                        String foreignSubStr1 = foreignStr.substring(findex1+1, 
findex2);
                        chatterMsg("\t\tcomparing english substr: " + 
englishSubStr1 + " with foreign substr " + foreignSubStr1);
                        if (!englishSubStr1.equals(foreignSubStr1))
                        {
                                logMsg("\t WARNING - not the same parameter or 
string in brackets for error: " + englishError);
                        }
                        englishStr=englishStr.substring(eindex2+1);
                        foreignStr=foreignStr.substring(findex2+1);
                }
        }       
        
        /**
         * check that strings without replacements only have
         * single quotes 
         * Note that we're passing in 'Character' but it's really only
         * thought about for quotes.
         * If the apostrophes are doubled, flag a warning.
         * Note that it may still be ok, we just want to know.  
         * 
         */
        private static void lookAtSingleQuotes (
                        String Str, String Character, String Error, String 
FileName ) 
        {
                String tmpStr = Str;
                int countOfCharacter = countCharacter(tmpStr, Character);
                //chatterMsg("\t\t\tcountOfCharacter for " + Character + " is: 
" + countOfCharacter);
                if (countOfCharacter < 0)
                        return;
                for (int m=0 ; m < countOfCharacter ; m++)
                {
                        int index1 = Str.indexOf("'");
                        String SubStr1 = Str.substring(index1);
                        int index2 = SubStr1.indexOf("'");
                        if (index2 < 0)  
                                return; // we're done
                        if (index2 == 0) // it *is* right after!
                        {
                                logMsg("\t WARNING - double quotes in String 
without replacements for ERROR: " + Error);
                        }
                        else
                                chatterMsg("\t\tfound: " + countOfCharacter + " 
single quotes");
                        tmpStr = SubStr1;
                }
        }

        /**
         * check that strings with replacements have doubled quotes
         * Note that we're passing in 'Character' but it's really only
         * thought about for quotes/apostrophes.
         * If the apostrophes are single FAIL, not OK.  
         * Note that we already know there *are* quotes in the string
         * 
         */
        private static void lookAtDoubleQuotes (
                        String Str, String Character, String Error, String 
FileName ) 
        {
                int countOfCharacter = countCharacter(Str, Character);
                if (countOfCharacter % 2 == 1)
                {
                        logMsg("\t WARNING - single quotes in String with 
replacements, for ERROR" + Error);
                }
                else
                        chatterMsg(" found: " + (countOfCharacter / 2) + " 
double quotes");
        }
        
        public static void compareUpperCaseStrings(String englishStr, String 
foreignStr, String Error, String FileName)
        {
                // first check to see if there are any strings with 
                // more than one uppercase.
                ArrayList englishArray = findUpperCaseStrings(englishStr);
                ArrayList foreignArray = findUpperCaseStrings(foreignStr);
                if ((englishArray == null) && (foreignArray==null))
                {
                        chatterMsg("no such character in string");
                        return;
                }
                else if ((englishArray == null) || (foreignArray == null))
                {
                        logMsg("\t FAILURE!!! - not the same number of 
Uppercase strings, one has none, the other something, ERROR: " + Error);
                        return;
                }
                if (englishArray.size() != foreignArray.size())
                {
                        logMsg("\t FAILURE!!! - not the same number of 
Uppercase strings for Error: " + Error);
                }
                else
                {
                        for (int i=0; i < englishArray.size(); i++)
                        {
                                if 
(!englishArray.get(i).equals(foreignArray.get(i)))
                                {
                                        logMsg("\t WARNING - difference in 
Uppercase strings for Error: " + Error);
                                }
                                else 
                                        chatterMsg("\t\tsuccessfully compared " 
+ englishArray.get(i));
                        }
                }
        }
        
        /**
         * 
         * Find uppercase strings in a string passed in
         */
        public static ArrayList findUpperCaseStrings(String Strin)
        {
                ArrayList StrArr = new ArrayList(); // for out
                StringBuffer buf = new StringBuffer();

                int length = Strin.length();
                for ( int upperIdx = 0 ; upperIdx < length ; ++upperIdx )
                {
                        char ch = Strin.charAt( upperIdx );
                        if ((buf == null) || (buf.length() == 0))
                        {
                                buf = new StringBuffer();
                                if (Character.isUpperCase(ch))
                                        buf.append(ch);
                        }
                        else if (buf.length() == 1)
                        {
                                if (Character.isUpperCase(ch))
                                        buf.append(ch);
                                else 
                                        buf = null; // never mind
                        }
                        else
                        {
                                if (Character.isUpperCase(ch))
                                        buf.append(ch);
                                else
                                {
                                        StrArr.add(buf.toString());
                                        buf = null;
                                }
                        }
                }
                return StrArr;
        }
        
        /**
     * Write message to the standard output.
     */
    private static void logMsg(String str)      {
        System.out.println(str);
    }

    /**
     * Write message to the standard output if property tvtdebug is true.
     */
    private static void chatterMsg(String str)  {
        String debug = System.getProperty("tvtdebug");
        if ((debug!=null) && (debug.equals("true")))
            System.out.println(str);
    }    
}

Attachment: checkBR.out
Description: Binary data

Reply via email to