2 * ******************************************************************************
\r
3 * Copyright (C) 2007, International Business Machines Corporation and others.
\r
4 * All Rights Reserved.
\r
5 * ******************************************************************************
\r
7 package com.ibm.icu.dev.tool.tzu;
\r
9 import java.awt.Image;
\r
10 import java.awt.Toolkit;
\r
11 import java.awt.event.WindowAdapter;
\r
12 import java.awt.event.WindowEvent;
\r
13 import java.io.File;
\r
14 import java.io.FileNotFoundException;
\r
15 import java.io.IOException;
\r
16 import java.net.URL;
\r
18 import javax.swing.JFrame;
\r
19 import javax.swing.JOptionPane;
\r
20 import javax.swing.WindowConstants;
\r
23 * Loads the ICUTZU tool, GUI version.
\r
25 public class GUILoader {
\r
27 * The title for the application.
\r
29 public static final String TITLE = "ICU4J Time Zone Update Utility (ICUTZU)";
\r
32 * The backup directory to store files.
\r
34 private File backupDir;
\r
37 * The tool's home directory.
\r
39 private File curDir;
\r
42 * The current logger.
\r
44 private Logger logger;
\r
47 * Whether the paths frame has been closed or not.
\r
49 private boolean pathClosed = false;
\r
52 * The frame that displays the path model component (<code>pathGUI</code>).
\r
54 private JFrame pathFrame;
\r
57 * The component that allows the user to interact with the path model.
\r
59 private PathComponent pathGUI;
\r
62 * The path model that stores all the paths and takes care of searching.
\r
64 private PathModel pathModel;
\r
67 * Whether the results frame has been closed or not.
\r
69 private boolean resultClosed = true;
\r
72 * The frame that displays the result model component (<code>resultGUI</code>).
\r
74 private JFrame resultFrame;
\r
77 * The component that allows the user to interact with the result model.
\r
79 private ResultComponent resultGUI;
\r
82 * The result model that stores all the results and takes care of updating.
\r
84 private ResultModel resultModel;
\r
87 * The source model that stores all the update sources and accesses the repository for more
\r
90 private SourceModel sourceModel;
\r
93 * The thread that partakes in the searching and updating.
\r
95 private Thread workerThread = null;
\r
98 * Entry point for the GUI version of the tool.
\r
101 * The base directory of the tool.
\r
103 * The location to store backups.
\r
105 * The file to load paths from.
\r
106 * @param resultFile
\r
107 * The file to load/save results to/from.
\r
109 * The local timezone resource file.
\r
113 public GUILoader(File curDir, File backupDir, File pathFile, File resultFile, File tzFile,
\r
115 // set the backup dir
\r
116 this.backupDir = backupDir;
\r
117 this.curDir = curDir;
\r
120 Image icon = Toolkit.getDefaultToolkit().getImage(iconFile.getAbsolutePath());
\r
122 // initialize the path list gui
\r
123 pathGUI = new PathComponent(this);
\r
124 pathFrame = new JFrame(TITLE + " - Directories to Search");
\r
125 pathFrame.getContentPane().add(pathGUI);
\r
127 pathFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
\r
128 pathFrame.setIconImage(icon);
\r
129 pathFrame.addWindowListener(new WindowAdapter() {
\r
130 public void windowClosing(WindowEvent event) {
\r
137 // initialize the result list gui
\r
138 resultGUI = new ResultComponent(this);
\r
139 resultFrame = new JFrame(TITLE + " - ICU4J Jar Files to Update");
\r
140 resultFrame.getContentPane().add(resultGUI);
\r
141 resultFrame.pack();
\r
142 resultFrame.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
\r
143 resultFrame.setIconImage(icon);
\r
144 resultFrame.addWindowListener(new WindowAdapter() {
\r
145 public void windowClosing(WindowEvent event) {
\r
148 resultClosed = true;
\r
153 // get the logger instance
\r
155 File logFile = new File(curDir.getPath(), "icutzugui.log");
\r
156 logger = Logger.getInstance(logFile, Logger.NORMAL, resultGUI, pathFrame);
\r
157 } catch (FileNotFoundException ex) {
\r
158 String error = "Could not open " + Logger.DEFAULT_FILENAME + " for writing.";
\r
159 System.out.println(error);
\r
160 JOptionPane.showMessageDialog(null, error, TITLE, JOptionPane.ERROR_MESSAGE);
\r
164 // initialize the models
\r
165 resultModel = new ResultModel(logger, resultFile);
\r
166 pathModel = new PathModel(logger, pathFile);
\r
167 sourceModel = new SourceModel(logger, tzFile);
\r
169 // attach the models to the guis
\r
170 resultGUI.setResultModel(resultModel);
\r
171 pathGUI.setPathModel(pathModel);
\r
172 resultGUI.setSourceModel(sourceModel);
\r
174 // load all the paths into the path model
\r
177 int verb = logger.getVerbosity();
\r
178 logger.setVerbosity(Logger.QUIET);
\r
179 pathModel.loadPaths();
\r
180 logger.setVerbosity(verb);
\r
181 } catch (IOException ex) {
\r
182 // failed to load the directory search file
\r
183 pathModel.addAllDrives();
\r
184 } catch (IllegalArgumentException ex) {
\r
185 // failed to load the directory search file
\r
186 pathModel.addAllDrives();
\r
189 // if the offline is not set to true, populate the list of available
\r
190 // timezone resource versions
\r
191 if (!"true".equalsIgnoreCase(System.getProperty("offline")))
\r
192 sourceModel.findSources();
\r
194 // make sure that search and update cancelation is disabled (since we
\r
195 // are initially neither updating nor searching, so there is nothing to
\r
197 setCancelSearchEnabled(false);
\r
198 setCancelUpdateEnabled(false);
\r
200 // show the path list gui
\r
201 pathFrame.setVisible(true);
\r
205 * Cancels a search.
\r
207 public void cancelSearch() {
\r
212 * Cancels an update.
\r
214 public void cancelUpdate() {
\r
219 * Searchs the selected paths in the path model.
\r
222 * Which paths in the path models to be used in the search.
\r
224 * Whether to search subdirectories.
\r
226 public void search(final int[] indices, final boolean subdirs) {
\r
229 workerThread = new Thread(new Runnable() {
\r
230 public void run() {
\r
232 logger.printlnToBoth("Search started ...");
\r
233 setCancelSearchEnabled(true);
\r
234 setUpdateEnabled(false);
\r
235 setSearchEnabled(false);
\r
236 resultFrame.setVisible(true);
\r
237 resultClosed = false;
\r
238 pathModel.search(resultModel, indices, subdirs, curDir, backupDir);
\r
239 logger.printlnToBoth("Search ended.");
\r
240 } catch (InterruptedException ex) {
\r
241 logger.printlnToBoth("Search interrupted.");
\r
243 setSearchEnabled(true);
\r
244 setUpdateEnabled(true);
\r
245 setCancelSearchEnabled(false);
\r
249 workerThread.start();
\r
253 * Searchs all the paths in the path model.
\r
256 * Whether to search subdirectories.
\r
258 public void searchAll(final boolean subdirs) {
\r
261 workerThread = new Thread(new Runnable() {
\r
262 public void run() {
\r
264 logger.printlnToBoth("Search started ...");
\r
265 setCancelSearchEnabled(true);
\r
266 setUpdateEnabled(false);
\r
267 setSearchEnabled(false);
\r
268 resultFrame.setVisible(true);
\r
269 resultClosed = false;
\r
270 pathModel.searchAll(resultModel, subdirs, curDir, backupDir);
\r
271 logger.printlnToBoth("Search ended.");
\r
272 } catch (InterruptedException ex) {
\r
273 logger.printlnToBoth("Search interrupted.");
\r
275 setSearchEnabled(true);
\r
276 setUpdateEnabled(true);
\r
277 setCancelSearchEnabled(false);
\r
281 workerThread.start();
\r
285 * Updates the selected results in the result model.
\r
288 * Which ICU4J jars in the result model to be used in the update.
\r
290 * The URL to use as the update for each ICU4J jar.
\r
292 public void update(final int[] indices, final URL updateURL) {
\r
295 workerThread = new Thread(new Runnable() {
\r
296 public void run() {
\r
298 logger.printlnToBoth("Update started ...");
\r
299 setCancelUpdateEnabled(true);
\r
300 setUpdateEnabled(false);
\r
301 setSearchEnabled(false);
\r
302 resultModel.update(indices, updateURL, backupDir);
\r
303 logger.printlnToBoth("Update ended.");
\r
304 } catch (InterruptedException ex) {
\r
305 // we want to know what was last being updated, so do not
\r
306 // change the status bar message
\r
308 // logger.setStatus("Update interrupted.");
\r
309 // } catch (InterruptedException e) {
\r
310 // // once is enough
\r
313 setUpdateEnabled(true);
\r
314 setSearchEnabled(true);
\r
315 setCancelUpdateEnabled(false);
\r
319 workerThread.start();
\r
323 * Updates all the results in the result model.
\r
326 * The URL to use as the update for each ICU4J jar.
\r
328 public void updateAll(final URL updateURL) {
\r
331 workerThread = new Thread(new Runnable() {
\r
332 public void run() {
\r
334 logger.printlnToBoth("Update started ...");
\r
335 setCancelUpdateEnabled(true);
\r
336 setUpdateEnabled(false);
\r
337 setSearchEnabled(false);
\r
338 resultModel.updateAll(updateURL, backupDir);
\r
339 logger.printlnToBoth("Update ended.");
\r
340 } catch (InterruptedException ex) {
\r
341 // we want to know what was last being updated, so do not
\r
342 // change the status bar message
\r
344 // logger.setStatus("Update interrupted.");
\r
345 // } catch (InterruptedException e) {
\r
346 // // once is enough
\r
349 setUpdateEnabled(true);
\r
350 setSearchEnabled(true);
\r
351 setCancelUpdateEnabled(false);
\r
355 workerThread.start();
\r
359 * Interrupts the worker thread and waits for it to finish.
\r
361 private void makeThreadDead() {
\r
362 if (workerThread != null)
\r
364 workerThread.interrupt();
\r
365 workerThread.join();
\r
366 } catch (Exception ex) {
\r
367 // do nothing -- if an exception was thrown, the worker thread
\r
368 // must have already been dead, which is perfectly fine
\r
373 * Sets whether the cancel search button should be enabled.
\r
376 * Whether the cancel search button should be enabled.
\r
378 private void setCancelSearchEnabled(boolean value) {
\r
379 resultGUI.setCancelSearchEnabled(value);
\r
383 * Sets whether the cancel update button should be enabled.
\r
386 * Whether the cancel update button should be enabled.
\r
388 private void setCancelUpdateEnabled(boolean value) {
\r
389 resultGUI.setCancelUpdateEnabled(value);
\r
393 * Sets whether the search button should be enabled.
\r
396 * Whether the search button should be enabled.
\r
398 private void setSearchEnabled(boolean value) {
\r
399 pathGUI.setSearchEnabled(value);
\r
403 * Sets whether the update button should be enabled.
\r
406 * Whether the update button should be enabled.
\r
408 private void setUpdateEnabled(boolean value) {
\r
409 resultGUI.setUpdateEnabled(value);
\r