/* | |
* ****************************************************************************** | |
* 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.File; | |
import java.io.FileNotFoundException; | |
import java.io.FileReader; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.Arrays; | |
import java.util.Iterator; | |
import java.util.List; | |
import javax.swing.AbstractListModel; | |
/** | |
* Represents a list of IncludePaths that is usable by any class that uses | |
* AbstractListModels (such as a JList in swing). Also contains methods to begin | |
* a search on those paths using ICUJarFinder and placing the results in a | |
* ResultModel, and methods to load a path list from a file. | |
*/ | |
class PathModel extends AbstractListModel { | |
/** | |
* The serializable UID. | |
*/ | |
public static final long serialVersionUID = 1337; | |
/** | |
* The list of paths as IncludePaths. | |
*/ | |
private List list = new ArrayList(); | |
/** | |
* The current logger. | |
*/ | |
private Logger logger; | |
/** | |
* The paths file where the paths are stored. | |
*/ | |
private File pathListFile; | |
/** | |
* The filename of the paths file where the paths are stored. | |
*/ | |
private String pathListFilename; | |
/** | |
* Constructs an empty path model. | |
* | |
* @param pathFile | |
* The file to load the path list from. | |
* @param logger | |
* The current logger. | |
*/ | |
public PathModel(Logger logger, File pathFile) { | |
this.logger = logger; | |
this.pathListFile = pathFile; | |
this.pathListFilename = pathFile.getName(); | |
} | |
/** | |
* Adds an IncludePath to the path list if it exists and is unique. | |
* | |
* @param path | |
* An existing path. | |
* @return Whether or not the given IncludePath exists. | |
*/ | |
public boolean add(IncludePath path) { | |
remove(path); | |
if (path.getPath().exists()) { | |
list.add(path); | |
int index = list.size() - 1; | |
fireIntervalAdded(this, index, index); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Adds a filename to the path list if it is valid and unique. The filename | |
* must either be of the form (<b>+</b>|<b>-</b>)<i>pathstring</i> and | |
* exist, or of the form <b>all</b>. In the case of the latter, all drives | |
* are added to the path list. | |
* | |
* @param includeFilename | |
* A filename in the form above. | |
* @return Whether or not <code>includeFilename</code> is both of the form | |
* detailed above and exists. | |
*/ | |
public boolean add(String includeFilename) { | |
if ("all".equals(includeFilename)) { | |
logger | |
.printlnToScreen("The tool will search all drives for ICU4J jars except any excluded directories specified"); | |
addAllDrives(); | |
return true; | |
} | |
return add(new IncludePath( | |
new File(includeFilename.substring(1).trim()), includeFilename | |
.charAt(0) == '+')); | |
} | |
/** | |
* Adds all drives to the path list. | |
*/ | |
public void addAllDrives() { | |
File[] roots = File.listRoots(); | |
for (int i = 0; i < roots.length; i++) | |
add(new IncludePath(roots[i], true)); | |
} | |
/** | |
* Returns the path at the element at a particular index of the path list. | |
* | |
* @param index | |
* The index of the element of the path list to return. | |
* @return The path at the specified index of the path list. Guaranteed to | |
* always be an IncludePath. | |
*/ | |
public Object getElementAt(int index) { | |
return list.get(index); | |
} | |
/** | |
* Returns the size of the path list. | |
* | |
* @return The size of the path list. | |
*/ | |
public int getSize() { | |
return (list == null) ? 0 : list.size(); | |
} | |
/** | |
* Returns an iterator of the path list. | |
* | |
* @return An iterator of the path list. | |
*/ | |
public Iterator iterator() { | |
return list.iterator(); | |
} | |
/** | |
* Loads a list of paths from the given path list file. Each path must be of | |
* the form | |
* | |
* @throws IOException | |
* @throws IllegalArgumentException | |
*/ | |
public void loadPaths() throws IOException, IllegalArgumentException { | |
logger.printlnToScreen("Scanning " + pathListFilename + " file..."); | |
logger.printlnToScreen(pathListFilename + " file contains"); | |
BufferedReader reader = null; | |
int lineNumber = 1; | |
String line; | |
char sign; | |
try { | |
reader = new BufferedReader(new FileReader(pathListFile)); | |
while (reader.ready()) { | |
line = reader.readLine().trim(); | |
if (line.length() >= 1) { | |
sign = line.charAt(0); | |
if (sign != '#') { | |
logger.printlnToScreen(line); | |
if (sign != '+' && sign != '-' && !"all".equals(line)) | |
pathListError( | |
"Each path entry must start with a + or - to denote inclusion/exclusion", | |
lineNumber); | |
if (!add(line)) | |
pathListError( | |
"\"" | |
+ line.substring(1).trim() | |
+ "\" is not a valid file or directory (perhaps it does not exist?)", | |
lineNumber); | |
} | |
} | |
lineNumber++; | |
} | |
} catch (FileNotFoundException ex) { | |
pathListError("The " + pathListFilename + " file doesn't exist."); | |
} catch (IOException ex) { | |
pathListError("Could not read the " + pathListFilename + " file."); | |
} finally { | |
try { | |
if (reader != null) | |
reader.close(); | |
} catch (IOException ex) { | |
} | |
} | |
} | |
/** | |
* Removes a path from the path list. Since there are no duplicates in the | |
* path list, this method either removes a single path or removes none. | |
* | |
* @param path | |
* The path to remove from the path list. | |
*/ | |
public void remove(IncludePath path) { | |
int index = list.indexOf(path); | |
if (index != -1) { | |
list.remove(index); | |
fireIntervalRemoved(this, index, index); | |
} | |
} | |
/** | |
* Removes a selection of paths from the path list by index. | |
* | |
* @param indices | |
* The indices of the path list to remove. | |
*/ | |
public void remove(int[] indices) { | |
if (list.size() > 0 && indices.length > 0) { | |
Arrays.sort(indices); | |
int max = indices[indices.length - 1]; | |
int min = indices[0]; | |
for (int i = indices.length - 1; i >= 0; i--) | |
list.remove(indices[i]); | |
fireIntervalRemoved(this, min, max); | |
} | |
} | |
/** | |
* Clears the path list. | |
*/ | |
public void removeAll() { | |
if (list.size() > 0) { | |
int index = list.size() - 1; | |
list.clear(); | |
fireIntervalRemoved(this, 0, index); | |
} | |
} | |
/** | |
* Searches a selection of paths in the path list for updatable ICU4J jars. | |
* Results are added to the result model. The indices provided are the | |
* indices of the path list to search. | |
* | |
* @param resultModel | |
* The result model to store the results of the search. | |
* @param indices | |
* The indices of the path list to use in the search. | |
* @param subdirs | |
* Whether to search subdiretories. | |
* @param curDir | |
* The base directory of the tool. | |
* @param backupDir | |
* Where to store backup files. | |
* @throws InterruptedException | |
*/ | |
public void search(ResultModel resultModel, int[] indices, boolean subdirs, | |
File curDir, File backupDir) throws InterruptedException { | |
if (list.size() > 0 && indices.length > 0) { | |
Arrays.sort(indices); | |
int n = indices.length; | |
IncludePath[] paths = new IncludePath[n]; | |
int k = 0; | |
Iterator iter = iterator(); | |
for (int i = 0; k < n && iter.hasNext(); i++) | |
if (i == indices[k]) | |
paths[k++] = (IncludePath) iter.next(); | |
else | |
iter.next(); | |
ICUJarFinder.search(resultModel, logger, paths, subdirs, curDir, | |
backupDir); | |
} | |
} | |
/** | |
* Searches each path in the path list for updatable ICU4J jars. Results are | |
* added to the result model. | |
* | |
* @param resultModel | |
* The result model to store the results of the search. | |
* @param subdirs | |
* Whether to search subdiretories. | |
* @param curDir | |
* The base directory of the tool. | |
* @param backupDir | |
* Where to store backup files. | |
* @throws InterruptedException | |
*/ | |
public void searchAll(ResultModel resultModel, boolean subdirs, | |
File curDir, File backupDir) throws InterruptedException { | |
if (list.size() > 0) { | |
int n = list.size(); | |
IncludePath[] paths = new IncludePath[n]; | |
Iterator iter = iterator(); | |
for (int i = 0; i < n; i++) | |
paths[i] = (IncludePath) iter.next(); | |
ICUJarFinder.search(resultModel, logger, paths, subdirs, curDir, | |
backupDir); | |
} | |
} | |
/** | |
* Throws an IOException with the specified message. | |
* | |
* @param message | |
* The message to put in the exception. | |
* @throws IOException | |
*/ | |
private void pathListError(String message) throws IOException { | |
throw new IOException("Error in " + pathListFilename + ": " + message); | |
} | |
/** | |
* Throws an IllegalArgumentException with the specified message and line | |
* number. | |
* | |
* @param message | |
* The message to put in the exception. | |
* @param lineNumber | |
* The line number to put in the exception. | |
* @throws IllegalArgumentException | |
*/ | |
private void pathListError(String message, int lineNumber) | |
throws IllegalArgumentException { | |
throw new IllegalArgumentException("Error in " + pathListFilename | |
+ " (line " + lineNumber + "): " + message); | |
} | |
} |