package com.jakeapp.gui.swing.helpers;
import java.util.ArrayList;
/**
* A duplicate-free list of strings, optionally persisted to disk.
* Strings at low-numbered indexes are older than those at high-numbered indexes.
* FIXME: we should put some bound on the amount of history we're prepared to keep.
*
* @author Phil Norman
*/
public class StringHistory {
// private static final ExecutorService executor = ThreadUtilities.newSingleThreadExecutor("StringHistory Writer");
private String filename;
private ArrayList<String> history;
/**
* Creates a new empty history that will not be written to disk.
*/
public StringHistory() {
this(null);
}
/**
* Creates a new history that starts with any history already on disk, and which writes changes out to disk as the occur.
* @param filename
*/
public StringHistory(String filename) {
this.filename = filename;
this.history = new ArrayList<String>();
readHistoryFile();
}
private void readHistoryFile() {
// TODO: core support!
}
public int size() {
return history.size();
}
public int getLatestHistoryIndex() {
return size() - 1;
}
public String get(int index) {
return history.get(index);
}
public void add(String string) {
if (string.length() == 0) {
return;
}
// Avoid duplicates by removing any old entry first.
history.remove(string);
history.add(string);
writeHistoryFile();
}
public void remove(String string) {
history.remove(string);
writeHistoryFile();
}
private void writeHistoryFile() {
// TODO: mock with core
}
public void clear() {
history = new ArrayList<String>();
if (filename != null) {
FileUtilities.fileFromString(filename).delete();
}
}
/*
/**
* Returns a list of all the strings in this history that match the given regular expression.
* The strings are returned oldest first.
* It's easy for a caller to sort the result, but it wouldn't be easy for the caller to infer the chronological ordering.
public List<String> getStringsMatching(String regularExpression) {
Pattern pattern = PatternUtilities.smartCaseCompile(regularExpression);
ArrayList<String> result = new ArrayList<String>();
for (String candidate : history) {
Matcher matcher = pattern.matcher(candidate);
if (matcher.find()) {
result.add(candidate);
}
}
return result;
}
private void readHistoryFile() {
try {
if (filename != null && FileUtilities.exists(filename)) {
for (String line : StringUtilities.readLinesFromFile(filename)) {
history.add(line);
}
}
} catch (Exception ex) {
Log.warn("Error reading history from file \"" + filename + "\".", ex);
}
}
private void writeHistoryFile() {
if (filename == null) {
return;
}
// Make sure that we don't write to disk off the EDT.
// FIXME: this relies on the calling code not calling us too frequently; a timer might be a better idea.
executor.execute(new Runnable() {
public void run() {
String error = StringUtilities.writeFile(FileUtilities.fileFromString(filename), history);
if (error != null) {
Log.warn("Failed to write history to file \"" + filename + "\" (" + error + ").");
}
}
});
}
*/
}