blob: fec3d87ce3d0bc99a1f4ecd0dcd776cfd61c1229 [file] [log] [blame]
/*
* ******************************************************************************
* 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.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
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[] { "Filename", "Path", "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 InputStreamReader(new FileInputStream(resultListFile),
"UTF-8"), 4 * 1024);
while ((line = reader.readLine()) != null) {
if (line.length() >= 1 && line.charAt(0) == '\ufeff')
line = line.substring(1);
line = line.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().getAbsoluteFile().equals(file.getAbsoluteFile())) {
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 OutputStreamWriter(
new FileOutputStream(resultListFile), "UTF-8"), 4 * 1024);
Iterator iter = iterator();
while (iter.hasNext()) {
icuFile = (ICUFile) iter.next();
String line = icuFile.getFile().getPath() + '\t' + icuFile.getTZVersion();
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 int update(int[] indices, URL updateURL, File backupDir) throws InterruptedException {
int numberFailed = 0;
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
logger.errorln(ex.getMessage());
numberFailed++;
}
else
iter.next();
}
return numberFailed;
}
/**
* 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 int updateAll(URL updateURL, File backupDir) throws InterruptedException {
int numberFailed = 0;
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
logger.errorln(ex.getMessage());
numberFailed++;
}
}
return numberFailed;
}
/**
* 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);
}
/**
* Logs as an error a given message and line number.
*
* @param message
* The message.
* @param lineNumber
* The line number.
*/
private void resultListError(String message, int lineNumber) {
logger.errorln("Error in " + resultListFilename + " (line " + lineNumber + "): " + message);
}
}