/* | |
* ****************************************************************************** | |
* Copyright (C) 2007, International Business Machines Corporation and others. | |
* All Rights Reserved. | |
* ****************************************************************************** | |
*/ | |
package com.ibm.icu.dev.tool.tzu; | |
import java.io.BufferedReader; | |
import java.io.BufferedWriter; | |
import java.io.File; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.net.URL; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Iterator; | |
import java.util.List; | |
import javax.swing.table.AbstractTableModel; | |
/** | |
* Represents a list of ICUFiles that is usable by any class that uses | |
* AbstractTableModels (such as a JTable in swing). Also contains methods to | |
* begin updates on those ICUFiles and methods to load and save a result list | |
* from and to a file. | |
*/ | |
class ResultModel extends AbstractTableModel { | |
/** | |
* The column designating filenames. | |
*/ | |
public static final int COLUMN_FILE_NAME = 0; | |
/** | |
* The column designating file paths. | |
*/ | |
public static final int COLUMN_FILE_PATH = 1; | |
/** | |
* The column designating ICU versions. | |
*/ | |
public static final int COLUMN_ICU_VERSION = 2; | |
/** | |
* The column designating timezone verisons. | |
*/ | |
public static final int COLUMN_TZ_VERSION = 3; | |
/** | |
* A list of names of the columns in a result model. | |
*/ | |
public static final String[] COLUMN_NAMES = new String[] { "Path", "Name", | |
"ICU Version", "TZ Version" }; | |
/** | |
* The serializable UID. | |
*/ | |
public static final long serialVersionUID = 1338; | |
/** | |
* The list of ICUFiles represented by this result model. | |
*/ | |
private List icuFileList = new ArrayList(); | |
/** | |
* The current logger. | |
*/ | |
private Logger logger; | |
/** | |
* The result list file where results are saved and stored. | |
*/ | |
private File resultListFile; | |
/** | |
* The filename of the result list file where results are saved and stored. | |
*/ | |
private String resultListFilename; | |
/** | |
* Constructs an empty result list. | |
* | |
* @param resultFile | |
* The file to load and save results from and to. | |
* @param logger | |
* The current logger. | |
*/ | |
public ResultModel(Logger logger, File resultFile) { | |
this.logger = logger; | |
this.resultListFile = resultFile; | |
this.resultListFilename = resultFile.getName(); | |
} | |
/** | |
* Adds a file to the ICUFile list. | |
* | |
* @param file | |
* The file. | |
* @return Whether the file was added successfully (which is determined by | |
* if it is an updatable ICU4J jar). | |
*/ | |
public boolean add(File file) { | |
try { | |
ICUFile icuFile = new ICUFile(file, logger); | |
add(icuFile); | |
return true; | |
} catch (IOException ex) { | |
return false; | |
} | |
} | |
/** | |
* Adds a file to the ICUFile list. | |
* | |
* @param icuFile | |
* The file. | |
*/ | |
public void add(ICUFile icuFile) { | |
remove(icuFile.getFile()); | |
icuFileList.add(icuFile); | |
int index = icuFileList.size() - 1; | |
fireTableRowsInserted(index, index); | |
} | |
/** | |
* Adds a file to the ICUFile list. | |
* | |
* @param filename | |
* The name of the file. | |
* @return Whether the file was added successfully (which is determined by | |
* if it is an updatable ICU4J jar). | |
*/ | |
public boolean add(String filename) { | |
return add(new File(filename)); | |
} | |
/** | |
* Returns the number of columns for each represented ICUFile. | |
* | |
* @return The number of columns for each represented ICUFile. | |
*/ | |
public int getColumnCount() { | |
return COLUMN_NAMES.length; | |
} | |
/** | |
* Returns the column names as stored in COLUMN_NAMES. | |
* | |
* @param col | |
* The index of the column. | |
* @return <code>COLUMN_NAMES[col]</code> | |
*/ | |
public String getColumnName(int col) { | |
return COLUMN_NAMES[col]; | |
} | |
/** | |
* Returns the number of ICUFiles represented. | |
* | |
* @return The number of ICUFiles represented. | |
*/ | |
public int getRowCount() { | |
return (icuFileList == null) ? 0 : icuFileList.size(); | |
} | |
/** | |
* Returns the item at the given row and column. The row determines which | |
* ICUFile is used, and the column determines which piece of data should be | |
* used. | |
* | |
* @param row | |
* Which ICU file to use. | |
* @param col | |
* Which piece of data to use. Should be one of the following: | |
* <ul> | |
* <li>COLUMN_FILE_PATH</li> | |
* <li>COLUMN_ICU_VERSION</li> | |
* <li>COLUMN_TZ_VERSION</li> | |
* </ul> | |
* @return The item at the given row and column. Will always be a String. | |
*/ | |
public Object getValueAt(int row, int col) { | |
ICUFile icuFile = ((ICUFile) icuFileList.get(row)); | |
switch (col) { | |
case COLUMN_FILE_NAME: | |
return icuFile.getFilename(); | |
case COLUMN_FILE_PATH: | |
return icuFile.getPath(); | |
case COLUMN_ICU_VERSION: | |
return icuFile.getICUVersion(); | |
case COLUMN_TZ_VERSION: | |
return icuFile.getTZVersion(); | |
default: | |
return null; | |
} | |
} | |
/** | |
* Returns an iterator on the list of ICUFiles. | |
* | |
* @return An iterator on the list of ICUFiles. | |
*/ | |
public Iterator iterator() { | |
return icuFileList.iterator(); | |
} | |
/** | |
* 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>. | |
* | |
* @throws IOException | |
* @throws IllegalArgumentException | |
*/ | |
public void loadResults() throws IOException, IllegalArgumentException { | |
logger.printlnToScreen("Scanning " + resultListFilename + " file..."); | |
logger.printlnToScreen(resultListFilename + " file contains"); | |
BufferedReader reader = null; | |
int lineNumber = 1; | |
String line; | |
int tab; | |
String filename; | |
try { | |
reader = new BufferedReader(new FileReader(resultListFile)); | |
while (reader.ready()) { | |
line = reader.readLine().trim(); | |
logger.printlnToScreen(line); | |
if (line.length() >= 1 && (tab = line.lastIndexOf('\t')) >= 0) { | |
if (!add(filename = line.substring(0, tab))) | |
resultListError(filename | |
+ " is not an updatable ICU4J file", lineNumber); | |
} | |
lineNumber++; | |
} | |
} catch (FileNotFoundException ex) { | |
resultListError("The " | |
+ resultListFilename | |
+ " file doesn't exist. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars."); | |
} catch (IOException ex) { | |
resultListError("Could not read the " | |
+ resultListFilename | |
+ " file. Please re-run the tool with -Ddiscoveronly=true option to generate the list of ICU4J jars."); | |
} finally { | |
try { | |
if (reader != null) | |
reader.close(); | |
} catch (IOException ex) { | |
} | |
} | |
} | |
/** | |
* Removes a file from the ICUFile list. | |
* | |
* @param file | |
* The file to remove. | |
*/ | |
public void remove(File file) { | |
if (icuFileList.size() > 0) { | |
Iterator iter = iterator(); | |
int i = 0; | |
while (iter.hasNext()) { | |
ICUFile icuFile = (ICUFile) iter.next(); | |
if (icuFile.getFile().equals(file)) { | |
icuFileList.remove(icuFile); | |
fireTableRowsDeleted(i, i); | |
return; | |
} | |
i++; | |
} | |
} | |
} | |
/** | |
* Removes a selection of files from the ICUFile list. | |
* | |
* @param indices | |
* The indices of the files to remove. | |
*/ | |
public void remove(int[] indices) { | |
if (icuFileList.size() > 0 && indices.length > 0) { | |
Arrays.sort(indices); | |
for (int i = indices.length - 1; i >= 0; i--) { | |
icuFileList.remove(indices[i]); | |
fireTableRowsDeleted(indices[i], indices[i]); | |
} | |
} | |
} | |
/** | |
* Clears the ICUFile list. | |
*/ | |
public void removeAll() { | |
if (icuFileList.size() > 0) { | |
int lastIndex = icuFileList.size() - 1; | |
icuFileList.clear(); | |
fireTableRowsDeleted(0, lastIndex); | |
} | |
} | |
/** | |
* 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>. | |
* | |
* @throws IOException | |
* @throws IllegalArgumentException | |
*/ | |
public void saveResults() throws IOException, IllegalArgumentException { | |
logger.printlnToScreen("Saving to file " + resultListFilename + " ..."); | |
BufferedWriter writer = null; | |
ICUFile icuFile = null; | |
try { | |
writer = new BufferedWriter(new FileWriter(resultListFile)); | |
Iterator iter = iterator(); | |
while (iter.hasNext()) { | |
icuFile = (ICUFile) iter.next(); | |
String line = icuFile.getFile().getPath() + '\t' | |
+ icuFile.getTZVersion() + "\n"; | |
logger.printlnToScreen(line); | |
writer.write(line); | |
} | |
} catch (FileNotFoundException ex) { | |
resultListError("Could not create the " + resultListFilename | |
+ " file."); | |
} catch (IOException ex) { | |
resultListError("Could not write to the " + resultListFilename | |
+ " file."); | |
} finally { | |
try { | |
if (writer != null) | |
writer.close(); | |
} catch (IOException ex) { | |
} | |
} | |
} | |
/** | |
* Updates a selection of the ICUFiles given a URL as the source of the | |
* update and a backup directory as a place to store a copy of the | |
* un-updated file. | |
* | |
* @param indices | |
* The indices of the ICUFiles to update. | |
* @param updateURL | |
* The URL to use a source of the update. | |
* @param backupDir | |
* The directory in which to store backups. | |
* @throws InterruptedException | |
*/ | |
public void update(int[] indices, URL updateURL, File backupDir) | |
throws InterruptedException { | |
if (icuFileList.size() > 0 && indices.length > 0) { | |
Arrays.sort(indices); | |
int n = indices.length; | |
int k = 0; | |
Iterator iter = iterator(); | |
for (int i = 0; k < n && iter.hasNext(); i++) | |
if (i == indices[k]) | |
try { | |
// update the file | |
((ICUFile) iter.next()).update(updateURL, backupDir); | |
fireTableRowsUpdated(i, i); | |
k++; | |
} catch (IOException ex) { | |
// could not update the jar | |
ex.printStackTrace(); | |
} | |
else | |
iter.next(); | |
} | |
} | |
/** | |
* Updates all of the ICUFiles given a URL as the source of the update and a | |
* backup directory as a place to store a copy of the un-updated file. | |
* | |
* @param updateURL | |
* The URL to use a source of the update. | |
* @param backupDir | |
* The directory in which to store backups. | |
* @throws InterruptedException | |
*/ | |
public void updateAll(URL updateURL, File backupDir) | |
throws InterruptedException { | |
if (icuFileList.size() > 0) { | |
int n = icuFileList.size(); | |
Iterator iter = iterator(); | |
for (int i = 0; i < n; i++) | |
try { | |
((ICUFile) iter.next()).update(updateURL, backupDir); | |
fireTableRowsUpdated(i, i); | |
} catch (IOException ex) { | |
// could not update the jar | |
ex.printStackTrace(); | |
} | |
} | |
} | |
/** | |
* Throws an IllegalArgumentException with the given message. | |
* | |
* @param message | |
* The message. | |
* @throws IllegalArgumentException | |
*/ | |
private void resultListError(String message) throws IOException { | |
throw new IOException("Error in " + resultListFilename + ": " + message); | |
} | |
/** | |
* Throws an IllegalArgumentException with the given message and line | |
* number. | |
* | |
* @param message | |
* The message. | |
* @param lineNumber | |
* The line number. | |
* @throws IllegalArgumentException | |
*/ | |
private void resultListError(String message, int lineNumber) | |
throws IllegalArgumentException { | |
throw new IllegalArgumentException("Error in " + resultListFilename | |
+ " (line " + lineNumber + "): " + message); | |
} | |
} |