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.io.BufferedReader;
\r
10 import java.io.BufferedWriter;
\r
11 import java.io.File;
\r
12 import java.io.FileInputStream;
\r
13 import java.io.FileNotFoundException;
\r
14 import java.io.FileOutputStream;
\r
15 import java.io.IOException;
\r
16 import java.io.InputStreamReader;
\r
17 import java.io.OutputStreamWriter;
\r
18 import java.net.URL;
\r
19 import java.util.ArrayList;
\r
20 import java.util.Arrays;
\r
21 import java.util.Iterator;
\r
22 import java.util.List;
\r
24 import javax.swing.table.AbstractTableModel;
\r
27 * Represents a list of ICUFiles that is usable by any class that uses AbstractTableModels (such as
\r
28 * a JTable in swing). Also contains methods to begin updates on those ICUFiles and methods to load
\r
29 * and save a result list from and to a file.
\r
31 class ResultModel extends AbstractTableModel {
\r
33 * The column designating filenames.
\r
35 public static final int COLUMN_FILE_NAME = 0;
\r
38 * The column designating file paths.
\r
40 public static final int COLUMN_FILE_PATH = 1;
\r
43 * The column designating ICU versions.
\r
45 public static final int COLUMN_ICU_VERSION = 2;
\r
48 * The column designating timezone verisons.
\r
50 public static final int COLUMN_TZ_VERSION = 3;
\r
53 * A list of names of the columns in a result model.
\r
55 public static final String[] COLUMN_NAMES = new String[] { "Filename", "Path", "ICU Version",
\r
59 * The serializable UID.
\r
61 public static final long serialVersionUID = 1338;
\r
64 * The list of ICUFiles represented by this result model.
\r
66 private List icuFileList = new ArrayList();
\r
69 * The current logger.
\r
71 private Logger logger;
\r
74 * The result list file where results are saved and stored.
\r
76 private File resultListFile;
\r
79 * The filename of the result list file where results are saved and stored.
\r
81 private String resultListFilename;
\r
84 * Constructs an empty result list.
\r
87 * The file to load and save results from and to.
\r
89 * The current logger.
\r
91 public ResultModel(Logger logger, File resultFile) {
\r
92 this.logger = logger;
\r
93 this.resultListFile = resultFile;
\r
94 this.resultListFilename = resultFile.getName();
\r
98 * Adds a file to the ICUFile list.
\r
102 * @return Whether the file was added successfully (which is determined by if it is an updatable
\r
105 public boolean add(File file) {
\r
107 ICUFile icuFile = new ICUFile(file, logger);
\r
110 } catch (IOException ex) {
\r
116 * Adds a file to the ICUFile list.
\r
121 public void add(ICUFile icuFile) {
\r
122 remove(icuFile.getFile());
\r
123 icuFileList.add(icuFile);
\r
124 int index = icuFileList.size() - 1;
\r
125 fireTableRowsInserted(index, index);
\r
129 * Adds a file to the ICUFile list.
\r
132 * The name of the file.
\r
133 * @return Whether the file was added successfully (which is determined by if it is an updatable
\r
136 public boolean add(String filename) {
\r
137 return add(new File(filename));
\r
141 * Returns the number of columns for each represented ICUFile.
\r
143 * @return The number of columns for each represented ICUFile.
\r
145 public int getColumnCount() {
\r
146 return COLUMN_NAMES.length;
\r
150 * Returns the column names as stored in COLUMN_NAMES.
\r
153 * The index of the column.
\r
154 * @return <code>COLUMN_NAMES[col]</code>
\r
156 public String getColumnName(int col) {
\r
157 return COLUMN_NAMES[col];
\r
161 * Returns the number of ICUFiles represented.
\r
163 * @return The number of ICUFiles represented.
\r
165 public int getRowCount() {
\r
166 return (icuFileList == null) ? 0 : icuFileList.size();
\r
170 * Returns the item at the given row and column. The row determines which ICUFile is used, and
\r
171 * the column determines which piece of data should be used.
\r
174 * Which ICU file to use.
\r
176 * Which piece of data to use. Should be one of the following:
\r
178 * <li>COLUMN_FILE_PATH</li>
\r
179 * <li>COLUMN_ICU_VERSION</li>
\r
180 * <li>COLUMN_TZ_VERSION</li>
\r
182 * @return The item at the given row and column. Will always be a String.
\r
184 public Object getValueAt(int row, int col) {
\r
185 ICUFile icuFile = ((ICUFile) icuFileList.get(row));
\r
187 case COLUMN_FILE_NAME:
\r
188 return icuFile.getFilename();
\r
189 case COLUMN_FILE_PATH:
\r
190 return icuFile.getPath();
\r
191 case COLUMN_ICU_VERSION:
\r
192 return icuFile.getICUVersion();
\r
193 case COLUMN_TZ_VERSION:
\r
194 return icuFile.getTZVersion();
\r
201 * Returns an iterator on the list of ICUFiles.
\r
203 * @return An iterator on the list of ICUFiles.
\r
205 public Iterator iterator() {
\r
206 return icuFileList.iterator();
\r
210 * Loads a list of ICUFiles from the given result list file. Lines should be of the form <b><i>pathstring</i><tab><i>tzversion</i></b>.
\r
212 * @throws IOException
\r
213 * @throws IllegalArgumentException
\r
215 public void loadResults() throws IOException, IllegalArgumentException {
\r
216 logger.printlnToScreen("Scanning " + resultListFilename + " file...");
\r
217 logger.printlnToScreen(resultListFilename + " file contains");
\r
219 BufferedReader reader = null;
\r
220 int lineNumber = 1;
\r
226 reader = new BufferedReader(new InputStreamReader(new FileInputStream(resultListFile),
\r
227 "UTF-8"), 4 * 1024);
\r
228 while ((line = reader.readLine()) != null) {
\r
229 if (line.length() >= 1 && line.charAt(0) == '\ufeff')
\r
230 line = line.substring(1);
\r
231 line = line.trim();
\r
232 logger.printlnToScreen(line);
\r
234 if (line.length() >= 1 && (tab = line.lastIndexOf('\t')) >= 0) {
\r
235 if (!add(filename = line.substring(0, tab)))
\r
236 resultListError(filename + " is not an updatable ICU4J file", lineNumber);
\r
241 } catch (FileNotFoundException ex) {
\r
242 resultListError("The "
\r
243 + resultListFilename
\r
244 + " file doesn't exist. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars.");
\r
245 } catch (IOException ex) {
\r
246 resultListError("Could not read the "
\r
247 + resultListFilename
\r
248 + " file. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars.");
\r
251 if (reader != null)
\r
253 } catch (IOException ex) {
\r
259 * Removes a file from the ICUFile list.
\r
262 * The file to remove.
\r
264 public void remove(File file) {
\r
265 if (icuFileList.size() > 0) {
\r
266 Iterator iter = iterator();
\r
268 while (iter.hasNext()) {
\r
269 ICUFile icuFile = (ICUFile) iter.next();
\r
270 if (icuFile.getFile().getAbsoluteFile().equals(file.getAbsoluteFile())) {
\r
271 icuFileList.remove(icuFile);
\r
272 fireTableRowsDeleted(i, i);
\r
281 * Removes a selection of files from the ICUFile list.
\r
284 * The indices of the files to remove.
\r
286 public void remove(int[] indices) {
\r
287 if (icuFileList.size() > 0 && indices.length > 0) {
\r
288 Arrays.sort(indices);
\r
289 for (int i = indices.length - 1; i >= 0; i--) {
\r
290 icuFileList.remove(indices[i]);
\r
291 fireTableRowsDeleted(indices[i], indices[i]);
\r
297 * Clears the ICUFile list.
\r
299 public void removeAll() {
\r
300 if (icuFileList.size() > 0) {
\r
301 int lastIndex = icuFileList.size() - 1;
\r
302 icuFileList.clear();
\r
303 fireTableRowsDeleted(0, lastIndex);
\r
308 * Saves a list of ICUFiles to the given result list file. Lines will be of the form <b><i>pathstring</i><tab><i>tzversion</i></b>.
\r
310 * @throws IOException
\r
311 * @throws IllegalArgumentException
\r
313 public void saveResults() throws IOException, IllegalArgumentException {
\r
314 logger.printlnToScreen("Saving to file " + resultListFilename + " ...");
\r
315 BufferedWriter writer = null;
\r
316 ICUFile icuFile = null;
\r
319 writer = new BufferedWriter(new OutputStreamWriter(
\r
320 new FileOutputStream(resultListFile), "UTF-8"), 4 * 1024);
\r
321 Iterator iter = iterator();
\r
322 while (iter.hasNext()) {
\r
323 icuFile = (ICUFile) iter.next();
\r
324 String line = icuFile.getFile().getPath() + '\t' + icuFile.getTZVersion();
\r
325 logger.printlnToScreen(line);
\r
326 writer.write(line);
\r
328 } catch (FileNotFoundException ex) {
\r
329 resultListError("Could not create the " + resultListFilename + " file.");
\r
330 } catch (IOException ex) {
\r
331 resultListError("Could not write to the " + resultListFilename + " file.");
\r
334 if (writer != null)
\r
336 } catch (IOException ex) {
\r
342 * Updates a selection of the ICUFiles given a URL as the source of the update and a backup
\r
343 * directory as a place to store a copy of the un-updated file.
\r
346 * The indices of the ICUFiles to update.
\r
348 * The URL to use a source of the update.
\r
350 * The directory in which to store backups.
\r
351 * @throws InterruptedException
\r
353 public int update(int[] indices, URL updateURL, File backupDir) throws InterruptedException {
\r
354 int numberFailed = 0;
\r
355 if (icuFileList.size() > 0 && indices.length > 0) {
\r
356 Arrays.sort(indices);
\r
357 int n = indices.length;
\r
360 Iterator iter = iterator();
\r
361 for (int i = 0; k < n && iter.hasNext(); i++)
\r
362 if (i == indices[k])
\r
365 ((ICUFile) iter.next()).update(updateURL, backupDir);
\r
366 fireTableRowsUpdated(i, i);
\r
368 } catch (IOException ex) {
\r
369 // could not update the jar
\r
370 logger.errorln(ex.getMessage());
\r
377 return numberFailed;
\r
381 * Updates all of the ICUFiles given a URL as the source of the update and a backup directory as
\r
382 * a place to store a copy of the un-updated file.
\r
385 * The URL to use a source of the update.
\r
387 * The directory in which to store backups.
\r
388 * @throws InterruptedException
\r
390 public int updateAll(URL updateURL, File backupDir) throws InterruptedException {
\r
391 int numberFailed = 0;
\r
392 if (icuFileList.size() > 0) {
\r
393 int n = icuFileList.size();
\r
394 Iterator iter = iterator();
\r
395 for (int i = 0; i < n; i++)
\r
397 ((ICUFile) iter.next()).update(updateURL, backupDir);
\r
398 fireTableRowsUpdated(i, i);
\r
399 } catch (IOException ex) {
\r
400 // could not update the jar
\r
401 logger.errorln(ex.getMessage());
\r
405 return numberFailed;
\r
409 * Throws an IllegalArgumentException with the given message.
\r
413 * @throws IllegalArgumentException
\r
415 private void resultListError(String message) throws IOException {
\r
416 throw new IOException("Error in " + resultListFilename + ": " + message);
\r
420 * Logs as an error a given message and line number.
\r
424 * @param lineNumber
\r
427 private void resultListError(String message, int lineNumber) {
\r
428 logger.errorln("Error in " + resultListFilename + " (line " + lineNumber + "): " + message);
\r