ICU-5606 fixed most of the logger issues, modified logging messages, overhauled the batch file, added a status bar, added safeguards against many exceptions, added some documentation, still plenty left to do

X-SVN-Rev: 21153
diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/CLILoader.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/CLILoader.java
index 62556a4..82a79ad 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/CLILoader.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/CLILoader.java
@@ -18,7 +18,6 @@
 

 import com.ibm.icu.dev.tool.UOption;

 

-

 public class CLILoader {

     public static void main(String[] args) {

         new CLILoader(args);

@@ -26,9 +25,6 @@
 

     public CLILoader(String[] args) {

         try {

-            // make sure the result model hides unreadable/unwritable files

-            resultModel.setHidden(false);

-

             // set some options to be true based on environment variables

             if ("true".equals(System.getProperty("discoveronly")))

                 options[DISCOVERONLY].doesOccur = true;

@@ -43,14 +39,12 @@
                 showHelp();

                 return;

             }

-            try{

-            // init the logger

-            logger = Logger.getInstance(Logger.DEFAULT_FILENAME,

-                    options[QUIET].doesOccur ? Logger.QUIET

-                            : options[VERBOSE].doesOccur ? Logger.VERBOSE

-                                    : Logger.NORMAL);

-            }catch(FileNotFoundException ex){

-                ex.printStackTrace();

+            try {

+                // init the logger

+                logger = Logger.getInstance(Logger.DEFAULT_FILENAME, options[QUIET].doesOccur ? Logger.QUIET

+                        : options[VERBOSE].doesOccur ? Logger.VERBOSE : Logger.NORMAL);

+            } catch (FileNotFoundException ex) {

+                System.out.println("Could not open " + Logger.DEFAULT_FILENAME + " for writing.");

                 System.exit(-1);

             }

             // create the resultModel, the pathModel, and the sourceModel

@@ -58,23 +52,23 @@
             pathModel = new PathModel(resultModel, logger);

             sourceModel = new SourceModel(logger);

 

+            // make sure the result model hides unreadable/unwritable files

+            resultModel.setHidden(false);

+

             // make sure only there is only one update mode in the options

-            int choiceType = (options[OFFLINE].doesOccur ? 1 : 0)

-                    + (options[TZVERSION].doesOccur ? 1 : 0)

-                    + (options[BEST].doesOccur ? 1 : 0)

-                    + (options[DISCOVERONLY].doesOccur ? 1 : 0);

+            int choiceType = (options[OFFLINE].doesOccur ? 1 : 0) + (options[TZVERSION].doesOccur ? 1 : 0)

+                    + (options[BEST].doesOccur ? 1 : 0) + (options[DISCOVERONLY].doesOccur ? 1 : 0);

             if (choiceType > 1)

-                syntaxError("Options -o (--offline), -t (--tzversion), -b (--best) and -d (--discoveronly) are mutually exclusive");// error

+                syntaxError("Options -o (--offline), -t (--tzversion), -b (--best) and -d (--discoveronly) are mutually exclusive");

 

             // make sure that quiet & verbose do not both occur

             if (options[QUIET].doesOccur && options[VERBOSE].doesOccur)

-                syntaxError("Options -q (--quiet) and -v (--verbose) are mutually exclusive");// error

+                syntaxError("Options -q (--quiet) and -v (--verbose) are mutually exclusive");

 

-            // make sure that exactly one of backup & nobackup occurs

             if (options[BACKUP].doesOccur && options[NOBACKUP].doesOccur)

-                syntaxError("Options -b (--backup) and -B (--nobackup) are mutually exclusive");// error

+                syntaxError("Options -b (--backup) and -B (--nobackup) are mutually exclusive");

             if (!options[BACKUP].doesOccur && !options[NOBACKUP].doesOccur)

-                syntaxError("One of the options -b (--backup) or -B (--nobackup) must occur");// error

+                syntaxError("One of the options -b (--backup) or -B (--nobackup) must occur");

             if (argsleft != 0)

                 syntaxError("Too many arguments");// error

 

@@ -98,9 +92,7 @@
 

             // if we're running offline and the local file doesnt exist, we

             // can't update squat

-            if (options[OFFLINE].doesOccur

-                    && !SourceModel.TZ_LOCAL_FILE.exists()

-                    && !options[DISCOVERONLY].doesOccur)

+            if (options[OFFLINE].doesOccur && !SourceModel.TZ_LOCAL_FILE.exists() && !options[DISCOVERONLY].doesOccur)

                 throw new IllegalArgumentException(

                         "Running offline mode but local file does not exist (no sources available)");

 

@@ -115,7 +107,7 @@
             // search the paths for updatable icu4j files

             try {

                 logger.println("Search started.", Logger.NORMAL);

-                pathModel.searchAll(options[RECURSE].doesOccur, backupDir);

+                pathModel.searchAll(options[RECURSE].doesOccur, backupDir, null);

                 logger.println("Search done.", Logger.NORMAL);

             } catch (InterruptedException ex) {

                 logger.println("Search interrupted.", Logger.NORMAL);

@@ -142,8 +134,7 @@
             // (do nothing in the case of DISCOVERONLY)

 

             // create a reader for user input

-            BufferedReader reader = new BufferedReader(new InputStreamReader(

-                    System.in));

+            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

 

             // iterate through each icu4j file in the search results

             Iterator resultIter = resultModel.iterator();

@@ -151,18 +142,12 @@
                 try {

                     ICUFile entry = (ICUFile) resultIter.next();

                     logger.println("", Logger.NORMAL);

-                    logger.println("Filename:  " + entry.getFile().getName(),

-                            Logger.NORMAL);

-                    logger.println("Location:  " + entry.getFile().getParent(),

-                            Logger.NORMAL);

-                    logger.println("Current Version: " + entry.getTZVersion(),

-                            Logger.NORMAL);

+                    logger.println("Filename:  " + entry.getFile().getName(), Logger.NORMAL);

+                    logger.println("Location:  " + entry.getFile().getParent(), Logger.NORMAL);

+                    logger.println("Current Version: " + entry.getTZVersion(), Logger.NORMAL);

 

-                    if (!entry.getFile().canRead()

-                            || !entry.getFile().canWrite()) {

-                        logger.println("Missing permissions for "

-                                + entry.getFile().getName() + ".",

-                                Logger.NORMAL);

+                    if (!entry.getFile().canRead() || !entry.getFile().canWrite()) {

+                        logger.println("Missing permissions for " + entry.getFile().getName() + ".", Logger.NORMAL);

                         continue;

                     }

 

@@ -172,8 +157,7 @@
                             update(entry, chosenName, chosenURL);

                     } else if (choiceType == 1) // confirmation mode

                     {

-                        String input = askConfirm(chosenName, chosenVersion,

-                                entry.getTZVersion(), reader);

+                        String input = askConfirm(chosenName, chosenVersion, entry.getTZVersion(), reader);

 

                         if ("yes".startsWith(input))

                             update(entry, chosenName, chosenURL);

@@ -188,8 +172,7 @@
                         else if ("local choice".startsWith(input))

                             update(entry, getLocalName(), getLocalURL());

                         else if (!"none".startsWith(input))

-                            update(entry, getTZVersionName(input),

-                                    getTZVersionURL(input));

+                            update(entry, getTZVersionName(input), getTZVersionURL(input));

                         else

                             skipUpdate();

                     }

@@ -207,18 +190,14 @@
         }

     }

 

-    private String askConfirm(String chosenString, String chosenVersion,

-            String currentVersion, BufferedReader reader) throws IOException {

+    private String askConfirm(String chosenString, String chosenVersion, String currentVersion, BufferedReader reader)

+            throws IOException {

         int betterness = chosenVersion.compareToIgnoreCase(currentVersion);

         if (betterness == 0) {

-            logger.println("Updating should have no effect on this file.",

-                    Logger.NORMAL);

+            logger.println("Updating should have no effect on this file.", Logger.NORMAL);

             logger.println("Update anyway?", Logger.NORMAL);

         } else if (betterness < 0) {

-            logger

-                    .println(

-                            "Warning: The version specified is older than the one present in the file.",

-                            Logger.NORMAL);

+            logger.println("Warning: The version specified is older than the one present in the file.", Logger.NORMAL);

             logger.println("Update anyway?", Logger.NORMAL);

         } else {

             logger.println("Update to " + chosenVersion + "?", Logger.NORMAL);

@@ -234,14 +213,11 @@
 

         logger.println(getLocalName(), Logger.NORMAL);

         while (sourceIter.hasNext())

-            logger.println(", " + ((Map.Entry) sourceIter.next()).getKey(),

-                    Logger.NORMAL);

+            logger.println(", " + ((Map.Entry) sourceIter.next()).getKey(), Logger.NORMAL);

         logger.println("", Logger.NORMAL);

 

-        logger

-                .println(

-                        "Update to which version? [best (default), none, local copy, <specific version above>]",

-                        Logger.NORMAL);

+        logger.println("Update to which version? [best (default), none, local copy, <specific version above>]",

+                Logger.NORMAL);

         logger.println(": ", Logger.NORMAL);

         return reader.readLine().trim().toLowerCase();

     }

@@ -294,8 +270,7 @@
 

     private URL getTZVersionURL(String version) {

         try {

-            return new URL(SourceModel.TZ_BASE_URLSTRING_START + version

-                    + SourceModel.TZ_BASE_URLSTRING_END);

+            return new URL(SourceModel.TZ_BASE_URLSTRING_START + version + SourceModel.TZ_BASE_URLSTRING_END);

         } catch (MalformedURLException ex) {

             ex.printStackTrace();

             return null;

@@ -318,18 +293,12 @@
 

     private File backupDir = null;

 

-    private static UOption options[] = new UOption[] {

-            UOption.create("help", '?', UOption.NO_ARG),

-            UOption.create("verbose", 'v', UOption.NO_ARG),

-            UOption.create("quiet", 'q', UOption.NO_ARG),

-            UOption.create("auto", 'a', UOption.NO_ARG),

-            UOption.create("offline", 'o', UOption.NO_ARG),

-            UOption.create("best", 'b', UOption.NO_ARG),

-            UOption.create("tzversion", 't', UOption.REQUIRES_ARG),

-            UOption.create("recurse", 'r', UOption.NO_ARG),

-            UOption.create("backup", 'b', UOption.REQUIRES_ARG),

-            UOption.create("nobackup", 'B', UOption.NO_ARG),

-            UOption.create("discoveronly", 'd', UOption.NO_ARG), };

+    private static UOption options[] = new UOption[] { UOption.create("help", '?', UOption.NO_ARG),

+            UOption.create("verbose", 'v', UOption.NO_ARG), UOption.create("quiet", 'q', UOption.NO_ARG),

+            UOption.create("auto", 'a', UOption.NO_ARG), UOption.create("offline", 'o', UOption.NO_ARG),

+            UOption.create("best", 'b', UOption.NO_ARG), UOption.create("tzversion", 't', UOption.REQUIRES_ARG),

+            UOption.create("recurse", 'r', UOption.NO_ARG), UOption.create("backup", 'b', UOption.REQUIRES_ARG),

+            UOption.create("nobackup", 'B', UOption.NO_ARG), UOption.create("discoveronly", 'd', UOption.NO_ARG), };

 

     private static final int HELP = 0;

 

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/GUILoader.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/GUILoader.java
index 19d323e..1aca6a8 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/GUILoader.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/GUILoader.java
@@ -13,8 +13,7 @@
 import java.net.URL;

 

 import javax.swing.JFrame;

-

-

+import javax.swing.text.JTextComponent;

 

 public class GUILoader {

     public static void main(String[] args) {

@@ -23,10 +22,11 @@
 

     public GUILoader() {

         String title = "ICU Time Zone Updater";

-        try{

+        try {

             logger = Logger.getInstance(Logger.DEFAULT_FILENAME, Logger.NORMAL);

-        }catch(FileNotFoundException ex){

-            // TODO: handle the exception gracefully

+        } catch (FileNotFoundException ex) {

+            System.out.println("Could not open " + Logger.DEFAULT_FILENAME + " for writing.");

+            System.exit(-1);

         }

         resultModel = new ResultModel(logger);

         pathModel = new PathModel(resultModel, logger);

@@ -63,6 +63,8 @@
             }

         });

 

+        statusBar = resultGUI.getStatusBar();

+

         // ask the user for a backup dir

         /***********************************************************************

          * JFileChooser backupChooser = new JFileChooser();

@@ -71,8 +73,7 @@
          * (backupChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) ?

          * backupChooser.getSelectedFile() : null; /

          **********************************************************************/

-        backupDir = new File(

-                "C:\\Documents and Settings\\Daniel Kesserich\\Desktop\\Spring 2007\\IBM\\backup");

+        backupDir = new File("C:\\Documents and Settings\\Daniel Kesserich\\Desktop\\Spring 2007\\IBM\\backup");

         /**/

 

         setCancelSearchEnabled(false);

@@ -94,7 +95,7 @@
                 try {

                     resultFrame.setVisible(true);

                     resultClosed = false;

-                    pathModel.searchAll(subdirs, backupDir);

+                    pathModel.searchAll(subdirs, backupDir, statusBar);

                 } catch (InterruptedException ex) { /* i escaped! i'm free! */

                 }

                 setSearchEnabled(true);

@@ -119,7 +120,7 @@
                 try {

                     resultFrame.setVisible(true);

                     resultClosed = false;

-                    pathModel.search(indices, subdirs, backupDir);

+                    pathModel.search(indices, subdirs, backupDir, statusBar);

                 } catch (InterruptedException ex) { /* i escaped! i'm free! */

                 }

                 setSearchEnabled(true);

@@ -235,4 +236,6 @@
     private File backupDir;

 

     private Logger logger;

+

+    private JTextComponent statusBar;

 }
\ No newline at end of file
diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUFile.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUFile.java
index fad9566..230ddc0 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUFile.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUFile.java
@@ -27,12 +27,14 @@
 

 import com.ibm.icu.util.UResourceBundle;

 

-

-

 public class ICUFile {

+    private ICUFile(Logger logger) {

+        this.logger = logger;

+    }

+

     public ICUFile(File file, Logger logger) throws IOException {

-        this.file = file;

-        ICUFile.logger = logger;

+        this.icuFile = file;

+        this.logger = logger;

 

         if (!file.isFile())

             throw new IOException("not a file");

@@ -41,26 +43,26 @@
         if (isSigned())

             throw new IOException("not a signed jar");

 

-        tzVersion = findEntryTZVersion(file, insertEntry);

+        tzVersion = findEntryTZVersion(file, tzEntry);

     }

 

     public File getFile() {

-        return file;

+        return icuFile;

     }

 

     public String getFilename() {

-        return file.getName();

+        return icuFile.getName();

     }

 

     public String getPath() {

-        String path = file.getPath();

+        String path = icuFile.getPath();

         int pos = path.lastIndexOf(File.separator);

         path = (pos == -1) ? "" : path.substring(0, pos);

         return path;

     }

 

     public String toString() {

-        return file.toString();

+        return icuFile.toString();

     }

 

     public String getICUVersion() {

@@ -72,29 +74,29 @@
     }

 

     public boolean equals(Object other) {

-        return (!(other instanceof ICUFile)) ? false : file

-                .equals(((ICUFile) other).file);

+        return (!(other instanceof ICUFile)) ? false : icuFile.getPath().equalsIgnoreCase(

+                ((ICUFile) other).icuFile.getPath());

     }

 

     public void updateJar(URL insertURL, File backupDir) throws IOException {

-        if (!file.canRead() || !file.canWrite())

-            throw new IOException("Missing permissions for " + file);

+        if (!icuFile.canRead() || !icuFile.canWrite())

+            throw new IOException("Missing permissions for " + icuFile);

         File backupFile = null;

-        if ((backupFile = createBackupFile(file, backupDir)) == null)

+        if ((backupFile = createBackupFile(icuFile, backupDir)) == null)

             throw new IOException("Failed to create a backup file.");

-        if (!copyFile(file, backupFile))

+        if (!copyFile(icuFile, backupFile))

             throw new IOException("Could not replace the original jar.");

-        if (!createUpdatedJar(backupFile, file, insertEntry, insertURL))

+        if (!createUpdatedJar(backupFile, icuFile, tzEntry, insertURL))

             throw new IOException("Could not create an updated jar.");

 

-        tzVersion = findEntryTZVersion(file, insertEntry);

+        tzVersion = findEntryTZVersion(icuFile, tzEntry);

     }

 

-    private static File createBackupFile(File inputFile, File backupBase) {

+    private File createBackupFile(File inputFile, File backupBase) {

+        logger.logln("Creating backup file for + " + inputFile + " at " + backupBase + ".", Logger.VERBOSE);

         String filename = inputFile.getName();

         String suffix = ".jar";

-        String prefix = filename.substring(0, filename.length()

-                - ".jar".length());

+        String prefix = filename.substring(0, filename.length() - ".jar".length());

 

         if (backupBase == null) {

             try {

@@ -107,21 +109,20 @@
         } else {

             File backupFile = null;

             File backupDesc = null;

-            File backupDir = new File(backupBase.getPath() + File.separator

-                    + prefix);

+            File backupDir = new File(backupBase.getPath() + File.separator + prefix);

             PrintStream ostream = null;

 

             try {

                 backupBase.mkdir();

                 backupDir.mkdir();

                 backupFile = File.createTempFile(prefix, suffix, backupDir);

-                backupDesc = new File(backupDir.toString() + File.separator

-                        + prefix + ".txt");

+                backupDesc = new File(backupDir.toString() + File.separator + prefix + ".txt");

                 backupDesc.createNewFile();

                 ostream = new PrintStream(new FileOutputStream(backupDesc));

                 ostream.println(inputFile.toString());

+                logger.logln("Successfully created backup file at " + backupFile + ".", Logger.VERBOSE);

             } catch (IOException ex) {

-                // ex.printStackTrace();

+                logger.logln("Failed to create backup file.", Logger.VERBOSE);

                 backupFile.delete();

                 backupDesc.delete();

                 backupDir.delete();

@@ -133,10 +134,8 @@
         }

     }

 

-    private static boolean copyFile(File inputFile, File outputFile) {

-        logger.println("Coping from " + inputFile + " to " + outputFile + ".",

-                Logger.VERBOSE);

-        logger.logln("Coping from " + inputFile + " to " + outputFile + ".");

+    private boolean copyFile(File inputFile, File outputFile) {

+        logger.logln("Copying from " + inputFile + " to " + outputFile + ".", Logger.VERBOSE);

         InputStream istream = null;

         OutputStream ostream = null;

         byte[] buffer = new byte[BUFFER_SIZE];

@@ -151,36 +150,28 @@
                 ostream.write(buffer, 0, bytesRead);

 

             success = true;

-            logger.println("Copy successful.", Logger.VERBOSE);

-            logger.logln("Copy successful.");

+            logger.logln("Copy successful.", Logger.VERBOSE);

         } catch (IOException ex) {

             outputFile.delete();

-            logger.println("Copy failed.", Logger.VERBOSE);

-            logger.logln("Copy failed.");

+            logger.logln("Copy failed.", Logger.VERBOSE);

         } finally {

             // safely close the streams

             if (istream != null)

                 try {

                     istream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (ostream != null)

                 try {

                     ostream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

         }

         return success;

     }

 

-    private static boolean copyEntry(File inputFile, JarEntry inputEntry,

-            File outputFile) {

-        logger.println("Coping from " + inputFile + "!/" + inputEntry + " to "

-                + outputFile + ".", Logger.VERBOSE);

-        logger.logln("Coping from " + inputFile + "!/" + inputEntry + " to "

-                + outputFile + ".");

+    private boolean copyEntry(File inputFile, JarEntry inputEntry, File outputFile) {

+        logger.logln("Copying from " + inputFile + "!/" + inputEntry + " to " + outputFile + ".", Logger.VERBOSE);

         JarFile jar = null;

         InputStream istream = null;

         OutputStream ostream = null;

@@ -197,43 +188,32 @@
                 ostream.write(buffer, 0, bytesRead);

 

             success = true;

-            logger.println("Copy successful.", Logger.VERBOSE);

-            logger.logln("Copy successful.");

+            logger.logln("Copy successful.", Logger.VERBOSE);

         } catch (IOException ex) {

-            // ex.printStackTrace();

             outputFile.delete();

-            logger.println("Copy failed.", Logger.VERBOSE);

-            logger.logln("Copy failed.");

+            logger.logln("Copy failed.", Logger.VERBOSE);

         } finally {

             // safely close the streams

             if (jar != null)

                 try {

                     jar.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (istream != null)

                 try {

                     istream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (ostream != null)

                 try {

                     ostream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

         }

         return success;

     }

 

-    private static boolean createUpdatedJar(File inputFile, File outputFile,

-            JarEntry insertEntry, URL inputURL) {

-        logger.println("Inserting " + inputURL + " into " + inputFile + "/"

-                + insertEntry + ".", Logger.VERBOSE);

-        logger.logln("Inserting " + inputURL + " into " + inputFile + "/"

-                + insertEntry + ".");

+    private boolean createUpdatedJar(File inputFile, File outputFile, JarEntry insertEntry, URL inputURL) {

         JarFile jar = null;

         JarOutputStream ostream = null;

         InputStream istream = null;

@@ -273,38 +253,31 @@
             }

 

             success = true;

-            logger.println("Insert successful.", Logger.VERBOSE);

-            logger.logln("Insert successful.");

+            logger.logln("Insert successful.", Logger.VERBOSE);

         } catch (IOException ex) {

-            // ex.printStackTrace();

             outputFile.delete();

-            logger.println("Insert failed.", Logger.VERBOSE);

-            logger.logln("Insert failed.");

+            logger.logln("Insert failed.", Logger.VERBOSE);

         } finally {

             // safely close the streams

             if (istream != null)

                 try {

                     istream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (ostream != null)

                 try {

                     ostream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (jstream != null)

                 try {

                     jstream.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

             if (jar != null)

                 try {

                     jar.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

         }

         return success;

@@ -315,39 +288,30 @@
         boolean success = false;

 

         try {

-            jar = new JarFile(file);

+            jar = new JarFile(icuFile);

             Manifest manifest = jar.getManifest();

-            if (manifest == null)

-                return hasFile(jar);

-            Iterator iter = manifest.getEntries().values().iterator();

-            while (iter.hasNext()) {

-                Attributes attr = (Attributes) iter.next();

-                icuTitle = attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);

-                icuVersion = attr

-                        .getValue(Attributes.Name.IMPLEMENTATION_VERSION);

-                if (!("ICU for Java".equals(icuTitle) || "Modularized ICU for Java"

-                        .equals(icuTitle)))

-                    continue;

-

-                // since it's an ICU file, we will search inside for the

-                // intended file

-                success = hasFile(jar);

-                break;

+            icuVersion = ICU_VERSION_UNKNOWN;

+            if (manifest != null) {

+                Iterator iter = manifest.getEntries().values().iterator();

+                while (iter.hasNext()) {

+                    Attributes attr = (Attributes) iter.next();

+                    String ver = attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);

+                    if (ver != null) {

+                        icuVersion = ver;

+                        break;

+                    }

+                }

             }

+            success = (jar.getJarEntry(TZ_ENTRY_DIR) != null) && hasFile(jar);

         } catch (IOException ex) {

-            // unable to create the JarFile,

-            // unable to get the Manifest

+            // unable to create the JarFile or unable to get the Manifest

             // log the unexplained i/o error, but we must drudge on

-            logger.println("I/O Error with " + file.getPath(), Logger.VERBOSE);

-            logger.logln("I/O Error with " + file.getPath());

-        } catch (Exception ex) {

-            // ex.printStackTrace();

+            logger.logln("I/O Error with " + icuFile.getPath(), Logger.VERBOSE);

         } finally {

             if (jar != null)

                 try {

                     jar.close();

                 } catch (IOException ex) {

-                    // ex.printStackTrace();

                 }

         }

         return success;

@@ -356,37 +320,39 @@
     private boolean hasFile(JarFile jar) {

         Enumeration e = jar.entries();

         while (e.hasMoreElements()) {

-            insertEntry = (JarEntry) e.nextElement();

-            if (insertEntry.getName().endsWith(UPDATE_FILENAME))

+            tzEntry = (JarEntry) e.nextElement();

+            if (tzEntry.getName().endsWith(TZ_ENTRY_FILENAME))

                 return true;

         }

         return false;

     }

 

     private boolean isSigned() {

-        return insertEntry.getCertificates() != null;

+        return tzEntry.getCertificates() != null;

     }

 

-    public static String findEntryTZVersion(File icuFile, JarEntry tzEntry) {

+    public String findEntryTZVersion(File icuFile, JarEntry tzEntry) {

         try {

             File temp = File.createTempFile("zoneinfo", ".res");

             temp.deleteOnExit();

             copyEntry(icuFile, tzEntry, temp);

             return findTZVersion(temp);

         } catch (IOException ex) {

-            logger.logln(ex.getMessage());

+            logger.errorln(ex.getMessage());

             return null;

         }

     }

 

-    public static String findFileTZVersion(File tzFile) {

+    public static String findFileTZVersion(File tzFile, Logger logger) {

+        ICUFile rawTZFile = new ICUFile(logger);

+

         try {

             File temp = File.createTempFile("zoneinfo", ".res");

             temp.deleteOnExit();

-            copyFile(tzFile, temp);

-            return findTZVersion(temp);

+            rawTZFile.copyFile(tzFile, temp);

+            return rawTZFile.findTZVersion(temp);

         } catch (IOException ex) {

-            logger.logln(ex.getMessage());

+            logger.errorln(ex.getMessage());

             return null;

         }

     }

@@ -398,21 +364,18 @@
      * ex) { ex.printStackTrace(); return null; } }

      */

 

-    private static String findTZVersion(File tzFile) {

+    private String findTZVersion(File tzFile) {

         try {

             String filename = tzFile.getName();

-            String entryname = filename.substring(0, filename.length()

-                    - ".res".length());

+            String entryname = filename.substring(0, filename.length() - ".res".length());

 

             URL url = new URL(tzFile.getParentFile().toURL().toString());

             ClassLoader loader = new URLClassLoader(new URL[] { url });

 

-            UResourceBundle bundle = UResourceBundle.getBundleInstance("",

-                    entryname, loader);

+            UResourceBundle bundle = UResourceBundle.getBundleInstance("", entryname, loader);

 

             String tzVersion;

-            if (bundle != null

-                    && (tzVersion = bundle.getString(TZ_VERSION_KEY)) != null)

+            if (bundle != null && (tzVersion = bundle.getString(TZ_VERSION_KEY)) != null)

                 return tzVersion;

         } catch (MissingResourceException ex) {

             // not an error -- some zoneinfo files do not have a version number

@@ -421,26 +384,28 @@
             ex.printStackTrace();

         }

 

-        return UNKNOWN_VERSION;

+        return TZ_VERSION_UNKNOWN;

     }

 

-    public static final String UPDATE_FILENAME = "zoneinfo.res";

-

     public static final int BUFFER_SIZE = 1024;

 

-    public static final String UNKNOWN_VERSION = "Unknown";

+    public static final String ICU_VERSION_UNKNOWN = "Unknown";

+

+    public static final String TZ_VERSION_UNKNOWN = "Unknown";

 

     public static final String TZ_VERSION_KEY = "TZVersion";

 

-    private File file;

+    public static final String TZ_ENTRY_DIR = "com/ibm/icu/impl";

 

-    private JarEntry insertEntry;

+    public static final String TZ_ENTRY_FILENAME = "zoneinfo.res";

 

-    private String icuTitle;

+    private File icuFile;

 

     private String icuVersion;

 

     private String tzVersion;

 

-    private static Logger logger;

+    private JarEntry tzEntry;

+

+    private Logger logger;

 }

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUJarFinder.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUJarFinder.java
index 6fd7b7d..ca2ce2d 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUJarFinder.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/ICUJarFinder.java
@@ -12,15 +12,14 @@
 import java.util.Iterator;

 import java.util.List;

 

-

+import javax.swing.text.JTextComponent;

 

 public class ICUJarFinder {

     private ICUJarFinder() {

     }

 

-    public static ResultModel search(ResultModel resultModel, Logger logger,

-            IncludePath[] paths, boolean subdirs, File backupDir)

-            throws InterruptedException {

+    public static ResultModel search(ResultModel resultModel, Logger logger, JTextComponent statusBar,

+            IncludePath[] paths, boolean subdirs, File backupDir) throws InterruptedException {

         List included = new ArrayList();

         List excluded = new ArrayList();

 

@@ -35,61 +34,59 @@
         if (backupDir != null)

             excluded.add(backupDir);

 

-        logger.println("*************", Logger.VERBOSE);

-        logger.println("Included:", Logger.VERBOSE);

+        logger.logln("*************", Logger.VERBOSE);

+        logger.logln("Search Paths", Logger.VERBOSE);

+        logger.logln("Included:", Logger.VERBOSE);

         for (int i = 0; i < included.size(); i++)

-            logger.println(included.get(i).toString(), Logger.VERBOSE);

-        logger.println("Excluded:", Logger.VERBOSE);

+            logger.logln(included.get(i).toString(), Logger.VERBOSE);

+        logger.logln("Excluded:", Logger.VERBOSE);

         for (int i = 0; i < excluded.size(); i++)

-            logger.println(excluded.get(i).toString(), Logger.VERBOSE);

-        logger.println("*************", Logger.VERBOSE);

+            logger.logln(excluded.get(i).toString(), Logger.VERBOSE);

+        logger.logln("*************", Logger.VERBOSE);

 

         for (int i = 0; i < included.size(); i++)

-            search(resultModel, logger, (File) included.get(i), excluded,

-                    subdirs, 0);

+            search(resultModel, logger, statusBar, (File) included.get(i), excluded, subdirs, 0);

 

         return resultModel;

     }

 

-    private static ResultModel search(ResultModel resultModel, Logger logger,

-            File file, List excluded, boolean subdirs, int depth)

-            throws InterruptedException {

+    private static ResultModel search(ResultModel resultModel, Logger logger, JTextComponent statusBar, File file,

+            List excluded, boolean subdirs, int depth) throws InterruptedException {

+        // check for interruptions

+        if (Thread.interrupted())

+            throw new InterruptedException();

+

+        // make sure the current file/directory isn't excluded

         Iterator iter = excluded.iterator();

         while (iter.hasNext())

-            if (file.getAbsolutePath().equalsIgnoreCase(

-                    ((File) iter.next()).getAbsolutePath()))

+            if (file.getAbsolutePath().equalsIgnoreCase(((File) iter.next()).getAbsolutePath()))

                 return resultModel;

 

         if (file.exists()) {

             if (file.isFile() && file.getName().endsWith(".jar")) {

                 try {

+                    // if the file/directory is an ICU jar file that we can

+                    // update, add it to the results

                     resultModel.add(new ICUFile(file, logger));

-                    logger.println("Added " + file.getPath() + ".",

-                            Logger.NORMAL);

-                    logger.logln("Added " + file.getPath() + ".");

+                    logger.logln("Added " + file.getPath() + ".", Logger.NORMAL);

                 } catch (IOException ex) {

-                    // if it's not an ICU file we care about, ignore it

-                    logger.println("Skipped " + file.getPath() + " ("

-                            + ex.getMessage() + ").", Logger.VERBOSE);

-                    logger.logln("Skipped " + file.getPath() + " ("

-                            + ex.getMessage() + ").");

+                    // if it's not an ICU jar file that we can update, ignore it

+                    logger.logln("Skipped " + file.getPath() + " (" + ex.getMessage() + ").", Logger.VERBOSE);

                 }

             } else if (file.isDirectory() && (subdirs || depth == 0)) {

+                // notify the user that something is happening

                 logger.println(file.getPath(), Logger.VERBOSE);

+                if (statusBar != null)

+                    statusBar.setText(file.getPath());

+

+                // recurse through each file/directory inside this directory

                 File[] dirlist = file.listFiles();

                 if (dirlist != null)

                     for (int i = 0; i < dirlist.length; i++)

-                        search(resultModel, logger, dirlist[i], excluded,

-                                subdirs, depth + 1);

-                if (Thread.interrupted())

-                    throw new InterruptedException();

-            } else if (file.isFile()

-                    && (file.getName().endsWith(".ear") || file.getName()

-                            .endsWith(".war"))) {

-                logger.logln("Skipped " + file.getPath()

-                        + " (ear/war files not supported).");

-                logger.println("Skipped " + file.getPath()

-                        + " (ear/war files not supported).", Logger.NORMAL);

+                        search(resultModel, logger, statusBar, dirlist[i], excluded, subdirs, depth + 1);

+            } else if (file.isFile() && (file.getName().endsWith(".ear") || file.getName().endsWith(".war"))) {

+                // for now, ear and .war

+                logger.logln("Skipped " + file.getPath() + " (ear/war files not supported).", Logger.NORMAL);

             }

         }

         return resultModel;

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/IncludePath.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/IncludePath.java
index 643d228..a51837e 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/IncludePath.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/IncludePath.java
@@ -28,8 +28,7 @@
     }

 

     public boolean equals(Object other) {

-        return !(other instanceof IncludePath) ? false : path

-                .equals(((IncludePath) other).path);

+        return !(other instanceof IncludePath) ? false : path.equals(((IncludePath) other).path);

     }

 

     private File path;

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/Logger.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/Logger.java
index 439144a..9901cdf 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/Logger.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/Logger.java
@@ -7,25 +7,25 @@
 

 package com.ibm.icu.dev.tool.tzu;

 

-import java.io.PrintStream;

-import java.io.FileOutputStream;

 import java.io.FileNotFoundException;

+import java.io.FileOutputStream;

+import java.io.PrintStream;

 

 public class Logger {

 

-    private Logger(String filename, int verbosity)throws FileNotFoundException {

+    private Logger(String filename, int verbosity) throws FileNotFoundException {

         System.out.println("Log file: " + filename);

-        if (logger.log != null)

-            logger.log.close();

-        logger.log = new PrintStream(new FileOutputStream(filename));

-        logger.verbosity = verbosity;

+        if (this.log != null)

+            this.log.close();

+        this.log = new PrintStream(new FileOutputStream(filename));

+        this.verbosity = verbosity;

     }

 

-    public static synchronized Logger getInstance(String filename, int verbosity) throws FileNotFoundException{

-       if(logger == null){

-           logger = new Logger(filename, verbosity);

-       }

-       return logger;

+    public static synchronized Logger getInstance(String filename, int verbosity) throws FileNotFoundException {

+        if (logger == null) {

+            logger = new Logger(filename, verbosity);

+        }

+        return logger;

     }

 

     public void setVerbosity(int verbosity) {

@@ -36,30 +36,40 @@
         return verbosity;

     }

 

+    public void log(String output, int verbosity) {

+        if (verbosity <= this.verbosity) {

+            System.out.print(output);

+            if (log != null)

+                log.print(output);

+        }

+    }

+

+    public void logln(String output, int verbosity) {

+        if (verbosity <= this.verbosity) {

+            System.out.println(output);

+            if (log != null)

+                log.println(output);

+        }

+    }

+

     public void print(String output, int verbosity) {

-        if (verbosity >= this.verbosity)

+        if (verbosity <= this.verbosity)

             System.out.print(output);

     }

 

     public void println(String output, int verbosity) {

-        if (verbosity >= this.verbosity)

+        if (verbosity <= this.verbosity)

             System.out.println(output);

     }

 

     public void error(String output) {

         System.err.print(output);

-    }

-

-    public void errorln(String output) {

-        System.err.println(output);

-    }

-

-    public void log(String output) {

         if (log != null)

             log.print(output);

     }

 

-    public void logln(String output) {

+    public void errorln(String output) {

+        System.err.println(output);

         if (log != null)

             log.println(output);

     }

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/PathComponent.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/PathComponent.java
index 53ab9ed..8977f53 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/PathComponent.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/PathComponent.java
@@ -30,7 +30,6 @@
 import javax.swing.JSeparator;

 import javax.swing.JTextField;

 

-

 public class PathComponent extends JComponent {

     public PathComponent(final GUILoader owner, final PathModel pathModel) {

         this.pathModel = pathModel;

@@ -89,8 +88,7 @@
 

             private void checkPopup(MouseEvent event) {

                 if (event.isPopupTrigger())

-                    pathPopup.show((Component) event.getSource(), event.getX(),

-                            event.getY());

+                    pathPopup.show((Component) event.getSource(), event.getX(), event.getY());

             }

         });

 

@@ -115,8 +113,7 @@
 

         pathSearchSelectedItem.addActionListener(new ActionListener() {

             public void actionPerformed(ActionEvent event) {

-                owner.search(pathList.getSelectedIndices(), pathSubdirOption

-                        .isSelected());

+                owner.search(pathList.getSelectedIndices(), pathSubdirOption.isSelected());

             }

         });

 

@@ -144,9 +141,22 @@
 

         pathBrowseButton.addActionListener(new ActionListener() {

             public void actionPerformed(ActionEvent event) {

+                // set the chooser's intial path to be whatever is in the text

+                // field

+                File path = new File(pathField.getText());

+                if (path.exists())

+                    pathChooser.setSelectedFile(path);

+

+                // run the chooser dialog

                 int returnVal = pathChooser.showOpenDialog(PathComponent.this);

-                if (returnVal == JFileChooser.APPROVE_OPTION)

-                    addFile(pathChooser.getSelectedFile());

+

+                // on an accept, add the path to the model and set the text

+                // field to it

+                if (returnVal == JFileChooser.APPROVE_OPTION) {

+                    path = pathChooser.getSelectedFile();

+                    addFile(path);

+                    pathField.setText(path.getPath());

+                }

             }

         });

 

@@ -159,9 +169,9 @@
 

     private void addFile(File file) {

         if (!pathModel.add(new IncludePath(file, isIncluded())))

-            JOptionPane.showMessageDialog(PathComponent.this, "\""

-                    + file.getPath() + "\" is not a valid file or path.",

-                    "Cannot add path/file", JOptionPane.ERROR_MESSAGE);

+            JOptionPane.showMessageDialog(PathComponent.this,

+                    "\"" + file.getPath() + "\" is not a valid file or path.", "Cannot add path/file",

+                    JOptionPane.ERROR_MESSAGE);

     }

 

     public void setSearchEnabled(boolean value) {

@@ -178,13 +188,11 @@
 

     private JList pathList = new JList();

 

-    private JComboBox pathSignBox = new JComboBox(new Object[] { "Include",

-            "Exclude" });

+    private JComboBox pathSignBox = new JComboBox(new Object[] { "Include", "Exclude" });

 

     private JTextField pathField = new JTextField(30);

 

-    private JCheckBox pathSubdirOption = new JCheckBox("Search Subdirectories",

-            true);

+    private JCheckBox pathSubdirOption = new JCheckBox("Search Subdirectories", true);

 

     private JButton pathBrowseButton = new JButton("Browse...");

 

@@ -194,16 +202,13 @@
 

     private JPopupMenu pathPopup = new JPopupMenu();

 

-    private JMenuItem pathAddAllDrivesItem = new JMenuItem(

-            "Add All Drives to List");

+    private JMenuItem pathAddAllDrivesItem = new JMenuItem("Add All Drives to List");

 

-    private JMenuItem pathRemoveSelectedItem = new JMenuItem(

-            "Remove Selected Items");

+    private JMenuItem pathRemoveSelectedItem = new JMenuItem("Remove Selected Items");

 

     private JMenuItem pathRemoveAllItem = new JMenuItem("Remove All");

 

-    private JMenuItem pathSearchSelectedItem = new JMenuItem(

-            "Search Selected Items");

+    private JMenuItem pathSearchSelectedItem = new JMenuItem("Search Selected Items");

 

     private JMenuItem pathSearchAllItem = new JMenuItem("Search All");

 

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/PathModel.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/PathModel.java
index 0fac2b9..f02a324 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/PathModel.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/PathModel.java
@@ -16,6 +16,7 @@
 import java.util.List;

 

 import javax.swing.AbstractListModel;

+import javax.swing.text.JTextComponent;

 

 class PathModel extends AbstractListModel {

     public PathModel(ResultModel resultModel, Logger logger) {

@@ -50,15 +51,11 @@
                     sign = line.charAt(0);

                     if (sign != '#') {

                         if (sign != '+' && sign != '-' && !"all".equals(line))

-                            pathlistError(

-                                    "Each path entry must start with a + or - to denote inclusion/exclusion",

+                            pathlistError("Each path entry must start with a + or - to denote inclusion/exclusion",

                                     lineNumber);// error

                         if (!add(line))

-                            pathlistError(

-                                    "\""

-                                            + line.substring(1).trim()

-                                            + "\" is not a valid file or directory (perhaps it does not exist?)",

-                                    lineNumber);// error

+                            pathlistError("\"" + line.substring(1).trim()

+                                    + "\" is not a valid file or directory (perhaps it does not exist?)", lineNumber);// error

                     }

                 }

 

@@ -80,8 +77,7 @@
             addAllDrives();

             return true;

         } else {

-            return add(new IncludePath(new File(filename.substring(1).trim()),

-                    filename.charAt(0) == '+'));

+            return add(new IncludePath(new File(filename.substring(1).trim()), filename.charAt(0) == '+'));

         }

     }

 

@@ -134,7 +130,7 @@
         }

     }

 

-    public void search(int[] indices, boolean subdirs, File backupDir)

+    public void search(int[] indices, boolean subdirs, File backupDir, JTextComponent statusBar)

             throws InterruptedException {

         if (list.size() > 0 && indices.length > 0) {

             Arrays.sort(indices);

@@ -149,25 +145,23 @@
                 else

                     iter.next();

 

-            ICUJarFinder.search(resultModel, logger, paths, subdirs, backupDir);

+            ICUJarFinder.search(resultModel, logger, statusBar, paths, subdirs, backupDir);

         }

     }

 

-    public void searchAll(boolean subdirs, File backupDir)

-            throws InterruptedException {

+    public void searchAll(boolean subdirs, File backupDir, JTextComponent statusBar) throws InterruptedException {

         if (list.size() > 0) {

             int n = list.size();

             IncludePath[] paths = new IncludePath[n];

             Iterator iter = list.iterator();

             for (int i = 0; i < n; i++)

                 paths[i] = (IncludePath) iter.next();

-            ICUJarFinder.search(resultModel, logger, paths, subdirs, backupDir);

+            ICUJarFinder.search(resultModel, logger, statusBar, paths, subdirs, backupDir);

         }

     }

 

     private static void pathlistError(String message, int lineNumber) {

-        throw new IllegalArgumentException("Error in " + PATHLIST_FILENAME

-                + " (line " + lineNumber + "): " + message);

+        throw new IllegalArgumentException("Error in " + PATHLIST_FILENAME + " (line " + lineNumber + "): " + message);

     }

 

     private List list = new ArrayList(); // list of paths (Files)

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultComponent.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultComponent.java
index d8ef71b..1d19537 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultComponent.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultComponent.java
@@ -32,10 +32,10 @@
 import javax.swing.JSeparator;

 import javax.swing.JTable;

 import javax.swing.JTextField;

+import javax.swing.text.JTextComponent;

 

 public class ResultComponent extends JComponent {

-    public ResultComponent(final GUILoader owner,

-            final ResultModel resultModel, final SourceModel sourceModel) {

+    public ResultComponent(final GUILoader owner, final ResultModel resultModel, final SourceModel sourceModel) {

         this.resultModel = resultModel;

         this.sourceModel = sourceModel;

 

@@ -94,8 +94,7 @@
 

             private void checkPopup(MouseEvent event) {

                 if (event.isPopupTrigger())

-                    resultPopup.show((Component) event.getSource(), event

-                            .getX(), event.getY());

+                    resultPopup.show((Component) event.getSource(), event.getX(), event.getY());

             }

         });

 

@@ -120,9 +119,7 @@
 

         resultUpdateSelectedItem.addActionListener(new ActionListener() {

             public void actionPerformed(ActionEvent event) {

-                owner

-                        .update(resultTable.getSelectedRows(),

-                                getSelectedSource());

+                owner.update(resultTable.getSelectedRows(), getSelectedSource());

             }

         });

 

@@ -156,8 +153,7 @@
 

         resultBrowseButton.addActionListener(new ActionListener() {

             public void actionPerformed(ActionEvent event) {

-                int returnVal = resultChooser

-                        .showOpenDialog(ResultComponent.this);

+                int returnVal = resultChooser.showOpenDialog(ResultComponent.this);

                 if (returnVal == JFileChooser.APPROVE_OPTION)

                     addFile(resultChooser.getSelectedFile());

             }

@@ -165,8 +161,7 @@
 

         resultHideOption.addItemListener(new ItemListener() {

             public void itemStateChanged(ItemEvent event) {

-                resultModel

-                        .setHidden(event.getStateChange() == ItemEvent.SELECTED);

+                resultModel.setHidden(event.getStateChange() == ItemEvent.SELECTED);

             }

         });

     }

@@ -177,9 +172,8 @@
 

     private boolean addFile(File file) {

         if (!resultModel.add(file)) {

-            JOptionPane.showMessageDialog(ResultComponent.this, "\""

-                    + file.toString() + "\" is not an updatable ICU jar file.",

-                    "Cannot add file", JOptionPane.ERROR_MESSAGE);

+            JOptionPane.showMessageDialog(ResultComponent.this, "\"" + file.toString()

+                    + "\" is not an updatable ICU jar file.", "Cannot add file", JOptionPane.ERROR_MESSAGE);

             return false;

         } else {

             return true;

@@ -198,6 +192,10 @@
         resultCancelUpdateButton.setEnabled(value);

     }

 

+    public JTextComponent getStatusBar() {

+        return statusBar;

+    }

+

     private JPanel resultInputPanel = new JPanel();

 

     // private JPanel resultTablePanel = new JPanel();

@@ -210,8 +208,7 @@
 

     private JTextField resultField = new JTextField(30);

 

-    private JCheckBox resultHideOption = new JCheckBox(

-            "Hide Unreadable/Unwritable Files", true);

+    private JCheckBox resultHideOption = new JCheckBox("Hide Unreadable/Unwritable Files", true);

 

     private JButton resultBrowseButton = new JButton("Browse...");

 

@@ -225,13 +222,11 @@
 

     private JPopupMenu resultPopup = new JPopupMenu();

 

-    private JMenuItem resultRemoveSelectedItem = new JMenuItem(

-            "Remove Selected Items");

+    private JMenuItem resultRemoveSelectedItem = new JMenuItem("Remove Selected Items");

 

     private JMenuItem resultRemoveAllItem = new JMenuItem("Remove All");

 

-    private JMenuItem resultUpdateSelectedItem = new JMenuItem(

-            "Update Selected Items");

+    private JMenuItem resultUpdateSelectedItem = new JMenuItem("Update Selected Items");

 

     private JMenuItem resultUpdateAllItem = new JMenuItem("Update All");

 

@@ -241,5 +236,7 @@
 

     private SourceModel sourceModel;

 

+    private JTextComponent statusBar = new JTextField(30);

+

     public static final long serialVersionUID = 1341;

 }

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultModel.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultModel.java
index f5087bb..d2469b8 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultModel.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/ResultModel.java
@@ -16,8 +16,6 @@
 

 import javax.swing.table.AbstractTableModel;

 

-

-

 class ResultModel extends AbstractTableModel {

     public ResultModel(Logger logger) {

         this.logger = logger;

@@ -39,18 +37,22 @@
     public Object getValueAt(int row, int col) {

         List list = hidden ? permissibleList : completeList;

         ICUFile entry = ((ICUFile) list.get(row));

-        return (col == COLUMN_FILE_NAME) ? entry.getPath()

-                : (col == COLUMN_FILE_PATH) ? entry.getFilename()

-                        : (col == COLUMN_ICU_VERSION) ? entry.getICUVersion()

-                                : (col == COLUMN_TZ_VERSION) ? entry

-                                        .getTZVersion()

-                                        : (col == COLUMN_READABLE) ? entry

-                                                .getFile().canRead() ? "Yes"

-                                                : "No"

-                                                : (col == COLUMN_WRITABLE) ? entry

-                                                        .getFile().canWrite() ? "Yes"

-                                                        : "No"

-                                                        : null;

+        switch (col) {

+        case COLUMN_FILE_NAME:

+            return entry.getPath();

+        case COLUMN_FILE_PATH:

+            return entry.getFilename();

+        case COLUMN_ICU_VERSION:

+            return entry.getICUVersion();

+        case COLUMN_TZ_VERSION:

+            return entry.getTZVersion();

+        case COLUMN_READABLE:

+            return entry.getFile().canRead() ? "Yes" : "No";

+        case COLUMN_WRITABLE:

+            return entry.getFile().canWrite() ? "Yes" : "No";

+        default:

+            return null;

+        }

     }

 

     public Iterator iterator() {

@@ -102,16 +104,14 @@
         removeAll(completeList, !hidden);

     }

 

-    public void update(int[] indices, URL updateURL, File backupDir)

-            throws InterruptedException {

+    public void update(int[] indices, URL updateURL, File backupDir) throws InterruptedException {

         if (hidden)

             update(permissibleList, indices, updateURL, backupDir);

         else

             update(completeList, indices, updateURL, backupDir);

     }

 

-    public void updateAll(URL updateURL, File backupDir)

-            throws InterruptedException {

+    public void updateAll(URL updateURL, File backupDir) throws InterruptedException {

         if (hidden)

             updateAll(permissibleList, updateURL, backupDir);

         else

@@ -164,8 +164,7 @@
         }

     }

 

-    private void update(List list, int[] indices, URL updateURL, File backupDir)

-            throws InterruptedException {

+    private void update(List list, int[] indices, URL updateURL, File backupDir) throws InterruptedException {

         if (list.size() > 0 && indices.length > 0) {

             Arrays.sort(indices);

             int n = indices.length;

@@ -188,8 +187,7 @@
         }

     }

 

-    private void updateAll(List list, URL updateURL, File backupDir)

-            throws InterruptedException {

+    private void updateAll(List list, URL updateURL, File backupDir) throws InterruptedException {

         if (list.size() > 0) {

             int n = list.size();

             Iterator iter = list.iterator();

@@ -205,8 +203,8 @@
         }

     }

 

-    public static final String[] COLUMN_NAMES = new String[] { "Path", "Name",

-            "ICU Version", "TZ Version", "Readable", "Writable" };

+    public static final String[] COLUMN_NAMES = new String[] { "Path", "Name", "ICU Version", "TZ Version", "Readable",

+            "Writable" };

 

     public static final int COLUMN_FILE_NAME = 0;

 

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/SourceModel.java b/icu4j/src/com/ibm/icu/dev/tool/tzu/SourceModel.java
index 384f96d..9572dfc 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/SourceModel.java
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/SourceModel.java
@@ -24,41 +24,42 @@
 

 class SourceModel extends AbstractListModel implements ComboBoxModel {

     public SourceModel(Logger logger) {

-        this.logger = logger;

-    }

-/*

-    public static void initialize(Logger logger) {

-        // cannot make TZ_BASE_URL and TZ_LOCAL_URL final since url creations

-        // need to be try-catched

-        try {

-            TZ_BASE_URL = new URL(TZ_BASE_URLSTRING_START);

+        // this.logger = logger;

 

-            if (!TZ_LOCAL_FILE.exists()) {

-                logger.errorln("Local copy (zoneinfo.res) does not exist.");

-            } else {

-                TZ_LOCAL_URL = TZ_LOCAL_FILE.toURL();

-                TZ_LOCAL_VERSION = ICUFile.findFileTZVersion(TZ_LOCAL_FILE);

-                if (TZ_LOCAL_VERSION == null) {

-                    logger.errorln("Failed to determine version of local copy");

+        // if all constants are not yet initialized

+        // (this is where they get initialized)

+        if (TZ_BASE_URL == null) {

+            try {

+                TZ_BASE_URL = new URL(TZ_BASE_URLSTRING_START);

+

+                if (!TZ_LOCAL_FILE.exists()) {

+                    // not a critical error, but we won't be able to use the

+                    // local tz file

+                    logger.errorln("Local copy (zoneinfo.res) does not exist");

                 } else {

-                    TZ_LOCAL_CHOICE = "Local Copy (" + TZ_LOCAL_VERSION + ")";

+                    TZ_LOCAL_URL = TZ_LOCAL_FILE.toURL();

+                    TZ_LOCAL_VERSION = ICUFile.findFileTZVersion(TZ_LOCAL_FILE, logger);

+                    if (TZ_LOCAL_VERSION == null) {

+                        logger.errorln("Failed to determine version of local copy");

+                        TZ_LOCAL_CHOICE = "Local Copy";

+                    } else {

+                        TZ_LOCAL_CHOICE = "Local Copy (" + TZ_LOCAL_VERSION + ")";

+                    }

                 }

+            } catch (MalformedURLException ex) {

+                // this shouldn't happen

+                ex.printStackTrace();

             }

-        } catch (MalformedURLException ex) {

-            // this shouldn't happen

-            ex.printStackTrace();

         }

     }

-*/

+

     public void findSources() {

         BufferedReader reader = null;

         try {

-            reader = new BufferedReader(new InputStreamReader(TZ_BASE_URL

-                    .openStream()));

+            reader = new BufferedReader(new InputStreamReader(TZ_BASE_URL.openStream()));

 

             HTMLEditorKit.ParserCallback htmlCallback = new HTMLEditorKit.ParserCallback() {

-                public void handleStartTag(HTML.Tag tag,

-                        MutableAttributeSet attr, int pos) {

+                public void handleStartTag(HTML.Tag tag, MutableAttributeSet attr, int pos) {

                     if (tag == HTML.Tag.LI)

                         listItem = true;

                 }

@@ -76,15 +77,13 @@
                         if (!"..".equals(str))

                             try {

                                 // add the new item to the map

-                                urlMap.put(str, new URL(TZ_BASE_URLSTRING_START

-                                        + str + TZ_BASE_URLSTRING_END));

+                                urlMap.put(str, new URL(TZ_BASE_URLSTRING_START + str + TZ_BASE_URLSTRING_END));

 

                                 // update the selected item and fire off an

                                 // event

                                 selected = (String) urlMap.lastKey();

                                 int index = 0;

-                                for (Iterator iter = urlMap.keySet().iterator(); iter

-                                        .hasNext();) {

+                                for (Iterator iter = urlMap.keySet().iterator(); iter.hasNext();) {

                                     if (iter.next().equals(str))

                                         index++;

                                 }

@@ -170,7 +169,9 @@
 

     public static final String TZ_BASE_URLSTRING_END = "/be/zoneinfo.res";

 

-    public static final File TZ_LOCAL_FILE = new File("zoneinfo.res");

+    public static final String TZ_LOCAL_FILENAME = "zoneinfo.res";

+

+    public static final File TZ_LOCAL_FILE = new File(TZ_LOCAL_FILENAME);

 

     public static String TZ_LOCAL_VERSION = null;

 

@@ -180,5 +181,5 @@
 

     public static final long serialVersionUID = 1339;

 

-    private Logger logger;

+    // private Logger logger;

 }

diff --git a/icu4j/src/com/ibm/icu/dev/tool/tzu/runicutzu.bat b/icu4j/src/com/ibm/icu/dev/tool/tzu/runicutzu.bat
index 6c53f5f..8784bcd 100644
--- a/icu4j/src/com/ibm/icu/dev/tool/tzu/runicutzu.bat
+++ b/icu4j/src/com/ibm/icu/dev/tool/tzu/runicutzu.bat
@@ -6,11 +6,13 @@
 rem *******************************************************************************

 rem */

 

+@echo.

 @echo *********** Welcome to the ICU4J Time Zone Update Utility (ICUTZU) ***********

 

 rem Set ICUTZU_HOME to the current directory.

 set ICUTZU_HOME=%~dp0

 @echo ICUTZU Home: %ICUTZU_HOME%

+@echo.

 

 rem Make sure certain files are present.

 IF NOT EXIST "%ICUTZU_HOME%icutzu.jar" GOTO MissingICUTZUJAR

@@ -19,41 +21,60 @@
 

 rem Set environmental variables.

 call "%ICUTZU_HOME%runicutzuenv.bat"

-rem Double-check that JAVA_HOME is set.

-@echo Java Home: %JAVA_HOME%

 IF NOT EXIST "%JAVA_HOME%\bin\java.exe" GOTO MissingJAVAHOME

 

-IF EXIST "%ICUTZU_HOME%Temp" GOTO Next

-rem Create a temporary directory.

+rem Create a temporary directory if one doesn't exit already.

+IF EXIST "%ICUTZU_HOME%Temp" GOTO TempAlreadyExists

 mkdir "%ICUTZU_HOME%Temp"

-:Next

+:TempAlreadyExists

+

+rem Collect all the arguments in this batch into a single variable.

+SET ARGS=

+:CollectArguments

+IF /I "%1"=="" GOTO :DoneCollectingArguments

+SET ARGS=%ARGS% %1

+SHIFT /1

+GOTO CollectArguments

+:DoneCollectingArguments

+

+

 

 rem Run the ICUTZU tool.

-@echo Launching the ICU4J Time Zone Update Utility (ICUTZU) ...

-@echo "%JAVA_HOME%\bin\java.exe" -cp "%ICUTZU_HOME%icu4j.jar";"%ICUTZU_HOME%icutzu.jar" -Dnogui=%NOGUI% -Ddiscoveronly=%DISCOVERONLY% -Dsilentpatch=%SILENTPATCH% com.ibm.icu.dev.tool.tzu.ICUTZUMain --recurse --backup "%ICUTZU_HOME%Temp" %1 %2 %3 %4 %5 %6 %7 %8 %9

-"%JAVA_HOME%\bin\java.exe" -cp "%ICUTZU_HOME%icu4j.jar";"%ICUTZU_HOME%icutzu.jar" -Dnogui=%NOGUI% -Ddiscoveronly=%DISCOVERONLY% -Dsilentpatch=%SILENTPATCH% com.ibm.icu.dev.tool.tzu.ICUTZUMain --recurse --backup "%ICUTZU_HOME%Temp" %1 %2 %3 %4 %5 %6 %7 %8 %9

-

-GOTO Exit

+@echo.

+@echo Launching the ICU4J Time Zone Update Utility (ICUTZU)...

+@echo "%JAVA_HOME%\bin\java.exe" -cp "%ICUTZU_HOME%icu4j.jar";"%ICUTZU_HOME%icutzu.jar" -Dnogui=%NOGUI% -Ddiscoveronly=%DISCOVERONLY% -Dsilentpatch=%SILENTPATCH% com.ibm.icu.dev.tool.tzu.ICUTZUMain --recurse --backup "%ICUTZU_HOME%Temp" %ARGS%

+@echo.

+"%JAVA_HOME%\bin\java.exe" -cp "%ICUTZU_HOME%icu4j.jar";"%ICUTZU_HOME%icutzu.jar" -Dnogui=%NOGUI% -Ddiscoveronly=%DISCOVERONLY% -Dsilentpatch=%SILENTPATCH% com.ibm.icu.dev.tool.tzu.ICUTZUMain --recurse --backup "%ICUTZU_HOME%Temp" %ARGS%

+IF ERRORLEVEL==0 GOTO Success

+GOTO Failure

 

 

 

 :MissingICUTZUJAR

 @echo The ICU4J Time Zone Update Utility (icutzu.jar) doesn't exist in %ICUTZU_HOME%.

 IF NOT EXIST "%ICUTZU_HOME%icu4j.jar" GOTO MissingICU4JJAR

-GOTO Exit

+GOTO Failure

 

 :MissingICU4JJAR

 @echo ICU for Java (icu4j.jar) doesn't exist in %ICUTZU_HOME%.

-GOTO Exit

+GOTO Failure

 

 :MissingICUTZUENV

 @echo runicutzuenv.bat file doesn't exist in %ICUTZU_HOME%.

-GOTO Exit

+GOTO Failure

 

 :MissingJAVAHOME

 @echo java.exe does not exist in %JAVA_HOME%\bin. Please update the JAVA_HOME enviroment variable in runicutzuenv.bat

+GOTO Failure

+

+:Success

+@echo.

+@echo End of ICU4J Time Zone Update Utility (ICUTZU) completed successfully.

 GOTO Exit

 

+:Failure

+@echo.

+@echo ICU4J Time Zone Update Utility (ICUTZU) did not complete successfully.

+GOTO Exit

 

 :Exit

-@echo End of ICU4J Time Zone Update Utility (ICUTZU).