diff --git a/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java b/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java index fea030774..c611fb053 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/AddressBook.java @@ -38,10 +38,12 @@ import net.i2p.util.SecureFile; * destinations. AddressBooks can be created from local and remote files, merged * together, and written out to local files. * + * Methods are NOT thread-safe. + * * @author Ragnarok * */ -class AddressBook { +class AddressBook implements Iterable> { private final String location; /** either addresses or subFile will be non-null, but not both */ @@ -107,7 +109,7 @@ class AddressBook { new File("addressbook.tmp").delete(); } */ - static final long MAX_SUB_SIZE = 3 * 1024 * 1024l; //about 5,000 hosts + static final long MAX_SUB_SIZE = 5 * 1024 * 1024l; //about 8,000 hosts /** * Construct an AddressBook from the Subscription subscription. If the diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java index 10119d844..aa67dfaac 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigIterator.java @@ -68,15 +68,14 @@ class ConfigIterator implements Iterator>, Closeable { if (next != null) return true; try { - String inputLine = input.readLine(); - while (inputLine != null) { + String inputLine; + while ((inputLine = input.readLine()) != null) { inputLine = ConfigParser.stripComments(inputLine); String[] splitLine = DataHelper.split(inputLine, "="); if (splitLine.length == 2) { next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); return true; } - inputLine = input.readLine(); } } catch (IOException ioe) {} try { input.close(); } catch (IOException ioe) {} diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java index 625b6e3d0..38985d00e 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java @@ -29,8 +29,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.StringReader; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -44,8 +44,7 @@ import net.i2p.util.SystemVersion; * Utility class providing methods to parse and write files in config file * format, and subscription file format. * - * TODO: Change file encoding from default to UTF-8? - * Or switch to the DataHelper loadProps/storeProps methods? + * TODO: switch to the DataHelper loadProps/storeProps methods? * * @author Ragnarok */ @@ -88,20 +87,21 @@ class ConfigParser { * if the BufferedReader cannot be read. * */ - public static Map parse(BufferedReader input) throws IOException { - Map result = new HashMap(); - String inputLine; - inputLine = input.readLine(); - while (inputLine != null) { - inputLine = stripComments(inputLine); - String[] splitLine = DataHelper.split(inputLine, "="); - if (splitLine.length == 2) { - result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); + private static Map parse(BufferedReader input) throws IOException { + try { + Map result = new HashMap(); + String inputLine; + while ((inputLine = input.readLine()) != null) { + inputLine = stripComments(inputLine); + String[] splitLine = DataHelper.split(inputLine, "="); + if (splitLine.length == 2) { + result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); + } } - inputLine = input.readLine(); + return result; + } finally { + try { input.close(); } catch (IOException ioe) {} } - input.close(); - return result; } /** @@ -114,15 +114,21 @@ class ConfigParser { * @throws IOException * if file cannot be read. */ - public static Map parse(File file) throws IOException { - FileInputStream fileStream = new FileInputStream(file); - BufferedReader input = new BufferedReader(new InputStreamReader( - fileStream, "UTF-8")); - Map rv = parse(input); + public static Map parse(File file) throws IOException { + FileInputStream fileStream = null; try { - fileStream.close(); - } catch (IOException ioe) {} - return rv; + fileStream = new FileInputStream(file); + BufferedReader input = new BufferedReader(new InputStreamReader( + fileStream, "UTF-8")); + Map rv = parse(input); + return rv; + } finally { + if (fileStream != null) { + try { + fileStream.close(); + } catch (IOException ioe) {} + } + } } /** @@ -135,11 +141,13 @@ class ConfigParser { * @throws IOException * if file cannot be read. */ - public static Map parse(String string) throws IOException { +/**** + public static Map parse(String string) throws IOException { StringReader stringReader = new StringReader(string); BufferedReader input = new BufferedReader(stringReader); return parse(input); } +****/ /** * Return a Map using the contents of the File file. If file cannot be read, @@ -152,8 +160,8 @@ class ConfigParser { * @return A Map containing the key, value pairs from file, or if file * cannot be read, map. */ - public static Map parse(File file, Map map) { - Map result; + public static Map parse(File file, Map map) { + Map result; try { result = parse(file); for (Map.Entry entry : map.entrySet()) { @@ -179,19 +187,21 @@ class ConfigParser { * @throws IOException * if input cannot be read. */ - public static List parseSubscriptions(BufferedReader input) + private static List parseSubscriptions(BufferedReader input) throws IOException { - List result = new LinkedList(); - String inputLine = input.readLine(); - while (inputLine != null) { - inputLine = stripComments(inputLine).trim(); - if (inputLine.length() > 0) { - result.add(inputLine); + try { + List result = new ArrayList(4); + String inputLine; + while ((inputLine = input.readLine()) != null) { + inputLine = stripComments(inputLine).trim(); + if (inputLine.length() > 0) { + result.add(inputLine); + } } - inputLine = input.readLine(); + return result; + } finally { + try { input.close(); } catch (IOException ioe) {} } - input.close(); - return result; } /** @@ -203,15 +213,21 @@ class ConfigParser { * @throws IOException * if file cannot be read. */ - public static List parseSubscriptions(File file) throws IOException { - FileInputStream fileStream = new FileInputStream(file); - BufferedReader input = new BufferedReader(new InputStreamReader( - fileStream, "UTF-8")); - List rv = parseSubscriptions(input); + private static List parseSubscriptions(File file) throws IOException { + FileInputStream fileStream = null; try { - fileStream.close(); - } catch (IOException ioe) {} - return rv; + fileStream = new FileInputStream(file); + BufferedReader input = new BufferedReader(new InputStreamReader( + fileStream, "UTF-8")); + List rv = parseSubscriptions(input); + return rv; + } finally { + if (fileStream != null) { + try { + fileStream.close(); + } catch (IOException ioe) {} + } + } } /** @@ -223,11 +239,13 @@ class ConfigParser { * @throws IOException * if string cannot be read. */ +/**** public static List parseSubscriptions(String string) throws IOException { StringReader stringReader = new StringReader(string); BufferedReader input = new BufferedReader(stringReader); return parseSubscriptions(input); } +****/ /** * Return a List using the contents of the File file. If file cannot be @@ -277,12 +295,15 @@ class ConfigParser { * @throws IOException * if the BufferedWriter cannot be written to. */ - public static void write(Map map, BufferedWriter output) throws IOException { - for (Map.Entry entry : map.entrySet()) { - output.write(entry.getKey() + '=' + entry.getValue()); - output.newLine(); + private static void write(Map map, BufferedWriter output) throws IOException { + try { + for (Map.Entry entry : map.entrySet()) { + output.write(entry.getKey() + '=' + entry.getValue()); + output.newLine(); + } + } finally { + try { output.close(); } catch (IOException ioe) {} } - output.close(); } /** @@ -299,7 +320,7 @@ class ConfigParser { * @throws IOException * if file cannot be written to. */ - public static void write(Map map, File file) throws IOException { + public static void write(Map map, File file) throws IOException { boolean success = false; if (!isWindows) { File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile()); @@ -327,13 +348,16 @@ class ConfigParser { * @throws IOException * if output cannot be written to. */ - public static void writeSubscriptions(List list, BufferedWriter output) + private static void writeSubscriptions(List list, BufferedWriter output) throws IOException { - for (String s : list) { - output.write(s); - output.newLine(); + try { + for (String s : list) { + output.write(s); + output.newLine(); + } + } finally { + try { output.close(); } catch (IOException ioe) {} } - output.close(); } /** @@ -347,7 +371,7 @@ class ConfigParser { * @throws IOException * if output cannot be written to. */ - public static void writeSubscriptions(List list, File file) + private static void writeSubscriptions(List list, File file) throws IOException { writeSubscriptions(list, new BufferedWriter( new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java b/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java index f0ed16569..1ce8c06e7 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Daemon.java @@ -23,9 +23,9 @@ package net.i2p.addressbook; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; @@ -130,11 +130,12 @@ public class Daemon { // yes, the EepGet fetch() is done in next() long start = System.currentTimeMillis(); AddressBook sub = iter.next(); - long end = System.currentTimeMillis(); // SubscriptionIterator puts in a dummy AddressBook with no location if no fetch is done - if (DEBUG && log != null && sub.getLocation() != null) + if (DEBUG && log != null && sub.getLocation() != null) { + long end = System.currentTimeMillis(); log.append("Fetch of " + sub.getLocation() + " took " + (end - start)); - start = end; + start = end; + } int old = 0, nnew = 0, invalid = 0, conflict = 0, total = 0; for (Iterator> eIter = sub.iterator(); eIter.hasNext(); ) { Map.Entry entry = eIter.next(); @@ -254,7 +255,7 @@ public class Daemon { } delay *= 60 * 60 * 1000; - List defaultSubs = new LinkedList(); + List defaultSubs = new ArrayList(4); // defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt"); defaultSubs.add(DEFAULT_SUB); diff --git a/apps/addressbook/java/src/net/i2p/addressbook/DaemonThread.java b/apps/addressbook/java/src/net/i2p/addressbook/DaemonThread.java index b0689a208..45a7893dd 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/DaemonThread.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/DaemonThread.java @@ -35,7 +35,7 @@ import net.i2p.util.I2PAppThread; */ public class DaemonThread extends I2PAppThread implements NamingServiceUpdater { - private String[] args; + private final String[] args; /** * Construct a DaemonThread with the command line arguments args. diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Log.java b/apps/addressbook/java/src/net/i2p/addressbook/Log.java index a87af2537..c6798f564 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Log.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Log.java @@ -36,7 +36,7 @@ import java.util.Date; */ class Log { - private File file; + private final File file; /** * Construct a Log instance that writes to the File file. diff --git a/apps/addressbook/java/src/net/i2p/addressbook/Subscription.java b/apps/addressbook/java/src/net/i2p/addressbook/Subscription.java index e391d11e2..26cb96eb8 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/Subscription.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/Subscription.java @@ -29,10 +29,8 @@ package net.i2p.addressbook; */ class Subscription { - private String location; - + private final String location; private String etag; - private String lastModified; private long lastFetched; @@ -41,14 +39,15 @@ class Subscription { * was last read at the time represented by etag and lastModified. * * @param location - * A String representing a url to a remote address book. + * A String representing a url to a remote address book. Non-null. * @param etag - * The etag header that we recieved the last time we read this - * subscription. + * The etag header that we received the last time we read this + * subscription. May be null. * @param lastModified - * the last-modified header we recieved the last time we read - * this subscription. - * @param lastFetched when the subscription was last fetched (Java time, as a String) + * the last-modified header we received the last time we read + * this subscription. May be null. + * @param lastFetched when the subscription was last fetched (Java time, as a String). + * May be null. */ public Subscription(String location, String etag, String lastModified, String lastFetched) { this.location = location; @@ -71,7 +70,7 @@ class Subscription { } /** - * Return the etag header that we recieved the last time we read this + * Return the etag header that we received the last time we read this * subscription. * * @return A String containing the etag header. @@ -91,7 +90,7 @@ class Subscription { } /** - * Return the last-modified header that we recieved the last time we read + * Return the last-modified header that we received the last time we read * this subscription. * * @return A String containing the last-modified header. diff --git a/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionIterator.java b/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionIterator.java index 74e946f95..4cab462c1 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionIterator.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionIterator.java @@ -37,9 +37,9 @@ import net.i2p.util.PortMapper; */ class SubscriptionIterator implements Iterator { - private Iterator subIterator; - private String proxyHost; - private int proxyPort; + private final Iterator subIterator; + private final String proxyHost; + private final int proxyPort; private final long delay; /** diff --git a/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionList.java b/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionList.java index 6aab49b22..d9135e4ff 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionList.java +++ b/apps/addressbook/java/src/net/i2p/addressbook/SubscriptionList.java @@ -23,8 +23,8 @@ package net.i2p.addressbook; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -34,19 +34,15 @@ import java.util.Map; * @author Ragnarok * */ -class SubscriptionList { +class SubscriptionList implements Iterable { - private List subscriptions; - - private File etagsFile; - - private File lastModifiedFile; - private File lastFetchedFile; + private final List subscriptions; + private final File etagsFile; + private final File lastModifiedFile; + private final File lastFetchedFile; private final long delay; - - private String proxyHost; - - private int proxyPort; + private final String proxyHost; + private final int proxyPort; /** * Construct a SubscriptionList using the urls from locationsFile and, if @@ -69,7 +65,7 @@ class SubscriptionList { public SubscriptionList(File locationsFile, File etagsFile, File lastModifiedFile, File lastFetchedFile, long delay, List defaultSubs, String proxyHost, int proxyPort) { - this.subscriptions = new LinkedList(); + this.subscriptions = new ArrayList(4); this.etagsFile = etagsFile; this.lastModifiedFile = lastModifiedFile; this.lastFetchedFile = lastFetchedFile; diff --git a/apps/addressbook/java/src/net/i2p/addressbook/package.html b/apps/addressbook/java/src/net/i2p/addressbook/package.html index cd4490657..f6c8243ed 100644 --- a/apps/addressbook/java/src/net/i2p/addressbook/package.html +++ b/apps/addressbook/java/src/net/i2p/addressbook/package.html @@ -1,7 +1,7 @@

-The addressbook application, which fetches hosts.txt files from subscription URLS via +The addressbook application, which fetches hosts.txt files from subscription URLs via HTTP and adds new hosts to the local database. While implemented as a webapp, this application contains no user interface. May also be packaged as a jar, as is done for Android.