Addressbook: Cleanups

in advance of new subscription protocol work:
- finals
- Add Iterable interfaces
- Comment out unused methods
- public->private methods
- Close resources in finally blocks
- Javadocs, spelling fixes
- Increase max subscription size
- LinkedList -> ArrayList
- Improve while loops for reading lines
This commit is contained in:
zzz
2016-04-16 18:35:46 +00:00
parent 696c2152b3
commit ebbf7f23ac
10 changed files with 117 additions and 96 deletions

View File

@@ -38,10 +38,12 @@ import net.i2p.util.SecureFile;
* destinations. AddressBooks can be created from local and remote files, merged * destinations. AddressBooks can be created from local and remote files, merged
* together, and written out to local files. * together, and written out to local files.
* *
* Methods are NOT thread-safe.
*
* @author Ragnarok * @author Ragnarok
* *
*/ */
class AddressBook { class AddressBook implements Iterable<Map.Entry<String, String>> {
private final String location; private final String location;
/** either addresses or subFile will be non-null, but not both */ /** either addresses or subFile will be non-null, but not both */
@@ -107,7 +109,7 @@ class AddressBook {
new File("addressbook.tmp").delete(); 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 * Construct an AddressBook from the Subscription subscription. If the

View File

@@ -68,15 +68,14 @@ class ConfigIterator implements Iterator<Map.Entry<String, String>>, Closeable {
if (next != null) if (next != null)
return true; return true;
try { try {
String inputLine = input.readLine(); String inputLine;
while (inputLine != null) { while ((inputLine = input.readLine()) != null) {
inputLine = ConfigParser.stripComments(inputLine); inputLine = ConfigParser.stripComments(inputLine);
String[] splitLine = DataHelper.split(inputLine, "="); String[] splitLine = DataHelper.split(inputLine, "=");
if (splitLine.length == 2) { if (splitLine.length == 2) {
next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); next = new ConfigEntry(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim());
return true; return true;
} }
inputLine = input.readLine();
} }
} catch (IOException ioe) {} } catch (IOException ioe) {}
try { input.close(); } catch (IOException ioe) {} try { input.close(); } catch (IOException ioe) {}

View File

@@ -29,8 +29,8 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.StringReader; import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; 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 * Utility class providing methods to parse and write files in config file
* format, and subscription file format. * format, and subscription file format.
* *
* TODO: Change file encoding from default to UTF-8? * TODO: switch to the DataHelper loadProps/storeProps methods?
* Or switch to the DataHelper loadProps/storeProps methods?
* *
* @author Ragnarok * @author Ragnarok
*/ */
@@ -88,20 +87,21 @@ class ConfigParser {
* if the BufferedReader cannot be read. * if the BufferedReader cannot be read.
* *
*/ */
public static Map<String, String> parse(BufferedReader input) throws IOException { private static Map<String, String> parse(BufferedReader input) throws IOException {
Map<String, String> result = new HashMap<String, String>(); try {
String inputLine; Map<String, String> result = new HashMap<String, String>();
inputLine = input.readLine(); String inputLine;
while (inputLine != null) { while ((inputLine = input.readLine()) != null) {
inputLine = stripComments(inputLine); inputLine = stripComments(inputLine);
String[] splitLine = DataHelper.split(inputLine, "="); String[] splitLine = DataHelper.split(inputLine, "=");
if (splitLine.length == 2) { if (splitLine.length == 2) {
result.put(splitLine[0].trim().toLowerCase(Locale.US), splitLine[1].trim()); 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 * @throws IOException
* if file cannot be read. * if file cannot be read.
*/ */
public static Map<String, String> parse(File file) throws IOException { public static Map<String, String> parse(File file) throws IOException {
FileInputStream fileStream = new FileInputStream(file); FileInputStream fileStream = null;
BufferedReader input = new BufferedReader(new InputStreamReader(
fileStream, "UTF-8"));
Map<String, String> rv = parse(input);
try { try {
fileStream.close(); fileStream = new FileInputStream(file);
} catch (IOException ioe) {} BufferedReader input = new BufferedReader(new InputStreamReader(
return rv; fileStream, "UTF-8"));
Map<String, String> rv = parse(input);
return rv;
} finally {
if (fileStream != null) {
try {
fileStream.close();
} catch (IOException ioe) {}
}
}
} }
/** /**
@@ -135,11 +141,13 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if file cannot be read. * if file cannot be read.
*/ */
public static Map<String, String> parse(String string) throws IOException { /****
public static Map<String, String> parse(String string) throws IOException {
StringReader stringReader = new StringReader(string); StringReader stringReader = new StringReader(string);
BufferedReader input = new BufferedReader(stringReader); BufferedReader input = new BufferedReader(stringReader);
return parse(input); return parse(input);
} }
****/
/** /**
* Return a Map using the contents of the File file. If file cannot be read, * 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 * @return A Map containing the key, value pairs from file, or if file
* cannot be read, map. * cannot be read, map.
*/ */
public static Map<String, String> parse(File file, Map<String, String> map) { public static Map<String, String> parse(File file, Map<String, String> map) {
Map<String, String> result; Map<String, String> result;
try { try {
result = parse(file); result = parse(file);
for (Map.Entry<String, String> entry : map.entrySet()) { for (Map.Entry<String, String> entry : map.entrySet()) {
@@ -179,19 +187,21 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if input cannot be read. * if input cannot be read.
*/ */
public static List<String> parseSubscriptions(BufferedReader input) private static List<String> parseSubscriptions(BufferedReader input)
throws IOException { throws IOException {
List<String> result = new LinkedList<String>(); try {
String inputLine = input.readLine(); List<String> result = new ArrayList<String>(4);
while (inputLine != null) { String inputLine;
inputLine = stripComments(inputLine).trim(); while ((inputLine = input.readLine()) != null) {
if (inputLine.length() > 0) { inputLine = stripComments(inputLine).trim();
result.add(inputLine); 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 * @throws IOException
* if file cannot be read. * if file cannot be read.
*/ */
public static List<String> parseSubscriptions(File file) throws IOException { private static List<String> parseSubscriptions(File file) throws IOException {
FileInputStream fileStream = new FileInputStream(file); FileInputStream fileStream = null;
BufferedReader input = new BufferedReader(new InputStreamReader(
fileStream, "UTF-8"));
List<String> rv = parseSubscriptions(input);
try { try {
fileStream.close(); fileStream = new FileInputStream(file);
} catch (IOException ioe) {} BufferedReader input = new BufferedReader(new InputStreamReader(
return rv; fileStream, "UTF-8"));
List<String> rv = parseSubscriptions(input);
return rv;
} finally {
if (fileStream != null) {
try {
fileStream.close();
} catch (IOException ioe) {}
}
}
} }
/** /**
@@ -223,11 +239,13 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if string cannot be read. * if string cannot be read.
*/ */
/****
public static List<String> parseSubscriptions(String string) throws IOException { public static List<String> parseSubscriptions(String string) throws IOException {
StringReader stringReader = new StringReader(string); StringReader stringReader = new StringReader(string);
BufferedReader input = new BufferedReader(stringReader); BufferedReader input = new BufferedReader(stringReader);
return parseSubscriptions(input); return parseSubscriptions(input);
} }
****/
/** /**
* Return a List using the contents of the File file. If file cannot be * Return a List using the contents of the File file. If file cannot be
@@ -277,12 +295,15 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if the BufferedWriter cannot be written to. * if the BufferedWriter cannot be written to.
*/ */
public static void write(Map<String, String> map, BufferedWriter output) throws IOException { private static void write(Map<String, String> map, BufferedWriter output) throws IOException {
for (Map.Entry<String, String> entry : map.entrySet()) { try {
output.write(entry.getKey() + '=' + entry.getValue()); for (Map.Entry<String, String> entry : map.entrySet()) {
output.newLine(); 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 * @throws IOException
* if file cannot be written to. * if file cannot be written to.
*/ */
public static void write(Map<String, String> map, File file) throws IOException { public static void write(Map<String, String> map, File file) throws IOException {
boolean success = false; boolean success = false;
if (!isWindows) { if (!isWindows) {
File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile()); File tmp = SecureFile.createTempFile("temp-", ".tmp", file.getAbsoluteFile().getParentFile());
@@ -327,13 +348,16 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if output cannot be written to. * if output cannot be written to.
*/ */
public static void writeSubscriptions(List<String> list, BufferedWriter output) private static void writeSubscriptions(List<String> list, BufferedWriter output)
throws IOException { throws IOException {
for (String s : list) { try {
output.write(s); for (String s : list) {
output.newLine(); output.write(s);
output.newLine();
}
} finally {
try { output.close(); } catch (IOException ioe) {}
} }
output.close();
} }
/** /**
@@ -347,7 +371,7 @@ class ConfigParser {
* @throws IOException * @throws IOException
* if output cannot be written to. * if output cannot be written to.
*/ */
public static void writeSubscriptions(List<String> list, File file) private static void writeSubscriptions(List<String> list, File file)
throws IOException { throws IOException {
writeSubscriptions(list, new BufferedWriter( writeSubscriptions(list, new BufferedWriter(
new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8"))); new OutputStreamWriter(new SecureFileOutputStream(file), "UTF-8")));

View File

@@ -23,9 +23,9 @@ package net.i2p.addressbook;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@@ -130,11 +130,12 @@ public class Daemon {
// yes, the EepGet fetch() is done in next() // yes, the EepGet fetch() is done in next()
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
AddressBook sub = iter.next(); AddressBook sub = iter.next();
long end = System.currentTimeMillis();
// SubscriptionIterator puts in a dummy AddressBook with no location if no fetch is done // 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)); log.append("Fetch of " + sub.getLocation() + " took " + (end - start));
start = end; start = end;
}
int old = 0, nnew = 0, invalid = 0, conflict = 0, total = 0; int old = 0, nnew = 0, invalid = 0, conflict = 0, total = 0;
for (Iterator<Map.Entry<String, String>> eIter = sub.iterator(); eIter.hasNext(); ) { for (Iterator<Map.Entry<String, String>> eIter = sub.iterator(); eIter.hasNext(); ) {
Map.Entry<String, String> entry = eIter.next(); Map.Entry<String, String> entry = eIter.next();
@@ -254,7 +255,7 @@ public class Daemon {
} }
delay *= 60 * 60 * 1000; delay *= 60 * 60 * 1000;
List<String> defaultSubs = new LinkedList<String>(); List<String> defaultSubs = new ArrayList<String>(4);
// defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt"); // defaultSubs.add("http://i2p/NF2RLVUxVulR3IqK0sGJR0dHQcGXAzwa6rEO4WAWYXOHw-DoZhKnlbf1nzHXwMEJoex5nFTyiNMqxJMWlY54cvU~UenZdkyQQeUSBZXyuSweflUXFqKN-y8xIoK2w9Ylq1k8IcrAFDsITyOzjUKoOPfVq34rKNDo7fYyis4kT5bAHy~2N1EVMs34pi2RFabATIOBk38Qhab57Umpa6yEoE~rbyR~suDRvD7gjBvBiIKFqhFueXsR2uSrPB-yzwAGofTXuklofK3DdKspciclTVzqbDjsk5UXfu2nTrC1agkhLyqlOfjhyqC~t1IXm-Vs2o7911k7KKLGjB4lmH508YJ7G9fLAUyjuB-wwwhejoWqvg7oWvqo4oIok8LG6ECR71C3dzCvIjY2QcrhoaazA9G4zcGMm6NKND-H4XY6tUWhpB~5GefB3YczOqMbHq4wi0O9MzBFrOJEOs3X4hwboKWANf7DT5PZKJZ5KorQPsYRSq0E3wSOsFCSsdVCKUGsAAAA/i2p/hosts.txt");
defaultSubs.add(DEFAULT_SUB); defaultSubs.add(DEFAULT_SUB);

View File

@@ -35,7 +35,7 @@ import net.i2p.util.I2PAppThread;
*/ */
public class DaemonThread extends I2PAppThread implements NamingServiceUpdater { public class DaemonThread extends I2PAppThread implements NamingServiceUpdater {
private String[] args; private final String[] args;
/** /**
* Construct a DaemonThread with the command line arguments args. * Construct a DaemonThread with the command line arguments args.

View File

@@ -36,7 +36,7 @@ import java.util.Date;
*/ */
class Log { class Log {
private File file; private final File file;
/** /**
* Construct a Log instance that writes to the File file. * Construct a Log instance that writes to the File file.

View File

@@ -29,10 +29,8 @@ package net.i2p.addressbook;
*/ */
class Subscription { class Subscription {
private String location; private final String location;
private String etag; private String etag;
private String lastModified; private String lastModified;
private long lastFetched; private long lastFetched;
@@ -41,14 +39,15 @@ class Subscription {
* was last read at the time represented by etag and lastModified. * was last read at the time represented by etag and lastModified.
* *
* @param location * @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 * @param etag
* The etag header that we recieved the last time we read this * The etag header that we received the last time we read this
* subscription. * subscription. May be null.
* @param lastModified * @param lastModified
* the last-modified header we recieved the last time we read * the last-modified header we received the last time we read
* this subscription. * this subscription. May be null.
* @param lastFetched when the subscription was last fetched (Java time, as a String) * @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) { public Subscription(String location, String etag, String lastModified, String lastFetched) {
this.location = location; 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. * subscription.
* *
* @return A String containing the etag header. * @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. * this subscription.
* *
* @return A String containing the last-modified header. * @return A String containing the last-modified header.

View File

@@ -37,9 +37,9 @@ import net.i2p.util.PortMapper;
*/ */
class SubscriptionIterator implements Iterator<AddressBook> { class SubscriptionIterator implements Iterator<AddressBook> {
private Iterator<Subscription> subIterator; private final Iterator<Subscription> subIterator;
private String proxyHost; private final String proxyHost;
private int proxyPort; private final int proxyPort;
private final long delay; private final long delay;
/** /**

View File

@@ -23,8 +23,8 @@ package net.i2p.addressbook;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -34,19 +34,15 @@ import java.util.Map;
* @author Ragnarok * @author Ragnarok
* *
*/ */
class SubscriptionList { class SubscriptionList implements Iterable<AddressBook> {
private List<Subscription> subscriptions; private final List<Subscription> subscriptions;
private final File etagsFile;
private File etagsFile; private final File lastModifiedFile;
private final File lastFetchedFile;
private File lastModifiedFile;
private File lastFetchedFile;
private final long delay; private final long delay;
private final String proxyHost;
private String proxyHost; private final int proxyPort;
private int proxyPort;
/** /**
* Construct a SubscriptionList using the urls from locationsFile and, if * Construct a SubscriptionList using the urls from locationsFile and, if
@@ -69,7 +65,7 @@ class SubscriptionList {
public SubscriptionList(File locationsFile, File etagsFile, public SubscriptionList(File locationsFile, File etagsFile,
File lastModifiedFile, File lastFetchedFile, long delay, List<String> defaultSubs, String proxyHost, File lastModifiedFile, File lastFetchedFile, long delay, List<String> defaultSubs, String proxyHost,
int proxyPort) { int proxyPort) {
this.subscriptions = new LinkedList<Subscription>(); this.subscriptions = new ArrayList<Subscription>(4);
this.etagsFile = etagsFile; this.etagsFile = etagsFile;
this.lastModifiedFile = lastModifiedFile; this.lastModifiedFile = lastModifiedFile;
this.lastFetchedFile = lastFetchedFile; this.lastFetchedFile = lastFetchedFile;

View File

@@ -1,7 +1,7 @@
<html> <html>
<body> <body>
<p> <p>
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. HTTP and adds new hosts to the local database.
While implemented as a webapp, this application contains no user interface. While implemented as a webapp, this application contains no user interface.
May also be packaged as a jar, as is done for Android. May also be packaged as a jar, as is done for Android.