From d193f23e4cd2086bd28586e9a70d2bf3c51f6866 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Mon, 27 Jun 2011 10:38:30 +0100
Subject: [PATCH] Replaced printlns with logging, moved delete() to FileUtils.

---
 .../sf/briar/db/DatabaseComponentImpl.java    | 23 +++++--
 components/net/sf/briar/db/H2Database.java    |  9 ++-
 components/net/sf/briar/db/JdbcDatabase.java  | 66 ++++++++++++-------
 .../db/ReadWriteLockDatabaseComponent.java    | 43 ++++++++----
 .../db/SynchronizedDatabaseComponent.java     | 49 +++++++++-----
 .../net/sf/briar/protocol/BatchImpl.java      |  2 +-
 test/net/sf/briar/util/FileUtilsTest.java     | 37 +++++++++++
 util/net/sf/briar/util/FileUtils.java         |  5 ++
 8 files changed, 168 insertions(+), 66 deletions(-)

diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java
index e0f447cdbd..db7dcc9da5 100644
--- a/components/net/sf/briar/db/DatabaseComponentImpl.java
+++ b/components/net/sf/briar/db/DatabaseComponentImpl.java
@@ -1,5 +1,8 @@
 package net.sf.briar.db;
 
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.NeighbourId;
@@ -14,6 +17,9 @@ import com.google.inject.Provider;
 
 abstract class DatabaseComponentImpl<Txn> implements DatabaseComponent {
 
+	private static final Logger LOG =
+		Logger.getLogger(DatabaseComponentImpl.class.getName());
+
 	protected final Database<Txn> db;
 	protected final Provider<Batch> batchProvider;
 
@@ -50,10 +56,10 @@ abstract class DatabaseComponentImpl<Txn> implements DatabaseComponent {
 		while(freeSpace < MIN_FREE_SPACE) {
 			// If disk space is critical, disable the storage of new messages
 			if(freeSpace < CRITICAL_FREE_SPACE) {
-				System.out.println("Critical cleanup");
+				if(LOG.isLoggable(Level.FINE)) LOG.fine("Critical cleanup");
 				writesAllowed = false;
 			} else {
-				System.out.println("Normal cleanup");
+				if(LOG.isLoggable(Level.FINE)) LOG.fine("Normal cleanup");
 			}
 			expireMessages(BYTES_PER_SWEEP);
 			Thread.yield();
@@ -80,15 +86,16 @@ abstract class DatabaseComponentImpl<Txn> implements DatabaseComponent {
 		synchronized(spaceLock) {
 			long now = System.currentTimeMillis();
 			if(bytesStoredSinceLastCheck > MAX_BYTES_BETWEEN_SPACE_CHECKS) {
-				System.out.println(bytesStoredSinceLastCheck
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine(bytesStoredSinceLastCheck
 						+ " bytes stored since last check");
 				bytesStoredSinceLastCheck = 0L;
 				timeOfLastCheck = now;
 				return true;
 			}
 			if(now - timeOfLastCheck > MAX_MS_BETWEEN_SPACE_CHECKS) {
-				System.out.println((now - timeOfLastCheck)
-						+ " ms since last check");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine((now - timeOfLastCheck) + " ms since last check");
 				bytesStoredSinceLastCheck = 0L;
 				timeOfLastCheck = now;
 				return true;
@@ -192,14 +199,16 @@ abstract class DatabaseComponentImpl<Txn> implements DatabaseComponent {
 				}
 			}
 		}
-		System.out.println(direct + " messages affected directly, "
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine(direct + " messages affected directly, "
 				+ indirect + " indirectly");
 	}
 
 	protected void waitForPermissionToWrite() {
 		synchronized(writeLock) {
 			while(!writesAllowed) {
-				System.out.println("Waiting for permission to write");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Waiting for permission to write");
 				try {
 					writeLock.wait();
 				} catch(InterruptedException ignored) {}
diff --git a/components/net/sf/briar/db/H2Database.java b/components/net/sf/briar/db/H2Database.java
index 4714b4ba05..28ae4f6c70 100644
--- a/components/net/sf/briar/db/H2Database.java
+++ b/components/net/sf/briar/db/H2Database.java
@@ -6,6 +6,8 @@ import java.sql.DriverManager;
 import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import net.sf.briar.api.crypto.Password;
 import net.sf.briar.api.db.DatabaseComponent;
@@ -18,6 +20,9 @@ import com.google.inject.Inject;
 
 class H2Database extends JdbcDatabase {
 
+	private static final Logger LOG =
+		Logger.getLogger(H2Database.class.getName());
+
 	private final Password password;
 	private final File home;
 	private final String url;
@@ -37,7 +42,7 @@ class H2Database extends JdbcDatabase {
 	}
 
 	public void close() throws DbException {
-		System.out.println("Closing database");
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Closing database");
 		try {
 			super.closeAllConnections();
 		} catch(SQLException e) {
@@ -51,7 +56,7 @@ class H2Database extends JdbcDatabase {
 		long used = getDiskSpace(dir);
 		long quota = DatabaseComponent.MAX_DB_SIZE - used;
 		long min =  Math.min(free, quota);
-		System.out.println("Free space: " + min);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Free space: " + min);
 		return min;
 	}
 
diff --git a/components/net/sf/briar/db/JdbcDatabase.java b/components/net/sf/briar/db/JdbcDatabase.java
index 79ac79f52d..3fbad792cc 100644
--- a/components/net/sf/briar/db/JdbcDatabase.java
+++ b/components/net/sf/briar/db/JdbcDatabase.java
@@ -14,6 +14,8 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
@@ -27,6 +29,7 @@ import net.sf.briar.api.protocol.GroupId;
 import net.sf.briar.api.protocol.Message;
 import net.sf.briar.api.protocol.MessageFactory;
 import net.sf.briar.api.protocol.MessageId;
+import net.sf.briar.util.FileUtils;
 
 abstract class JdbcDatabase implements Database<Connection> {
 
@@ -141,6 +144,9 @@ abstract class JdbcDatabase implements Database<Connection> {
 	private static final String INDEX_STATUSES_BY_NEIGHBOUR =
 		"CREATE INDEX statusesByNeighbour ON statuses (neighbourId)";
 
+	private static final Logger LOG =
+		Logger.getLogger(JdbcDatabase.class.getName());
+
 	private final MessageFactory messageFactory;
 	private final String hashType;
 	private final LinkedList<Connection> connections =
@@ -161,9 +167,10 @@ abstract class JdbcDatabase implements Database<Connection> {
 		if(resume) {
 			assert dir.exists();
 			assert dir.isDirectory();
-			System.out.println("Resuming from " + dir.getPath());
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Resuming from " + dir.getPath());
 		} else {
-			if(dir.exists()) delete(dir);
+			if(dir.exists()) FileUtils.delete(dir);
 		}
 		try {
 			Class.forName(driverClass);
@@ -173,8 +180,10 @@ abstract class JdbcDatabase implements Database<Connection> {
 		Connection txn = startTransaction("initialize");
 		try {
 			// If not resuming, create the tables
-			if(resume)
-				System.out.println(getNumberOfMessages(txn) + " messages");
+			if(resume) {
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine(getNumberOfMessages(txn) + " messages");
+			}
 			else createTables(txn);
 			commitTransaction(txn);
 		} catch(DbException e) {
@@ -183,40 +192,44 @@ abstract class JdbcDatabase implements Database<Connection> {
 		}
 	}
 
-	private void delete(File f) {
-		if(f.isDirectory()) for(File child : f.listFiles()) delete(child);
-		System.out.println("Deleting " + f.getPath());
-		f.delete();
-	}
-
 	private void createTables(Connection txn) throws DbException {
 		Statement s = null;
 		try {
 			s = txn.createStatement();
-			System.out.println("Creating localSubscriptions table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating localSubscriptions table");
 			s.executeUpdate(insertHashType(CREATE_LOCAL_SUBSCRIPTIONS));
-			System.out.println("Creating messages table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating messages table");
 			s.executeUpdate(insertHashType(CREATE_MESSAGES));
 			s.executeUpdate(INDEX_MESSAGES_BY_PARENT);
 			s.executeUpdate(INDEX_MESSAGES_BY_AUTHOR);
 			s.executeUpdate(INDEX_MESSAGES_BY_TIMESTAMP);
 			s.executeUpdate(INDEX_MESSAGES_BY_SENDABILITY);
-			System.out.println("Creating neighbours table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating neighbours table");
 			s.executeUpdate(insertHashType(CREATE_NEIGHBOURS));
-			System.out.println("Creating batchesToAck table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating batchesToAck table");
 			s.executeUpdate(insertHashType(CREATE_BATCHES_TO_ACK));
-			System.out.println("Creating neighbourSubscriptions table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating neighbourSubscriptions table");
 			s.executeUpdate(insertHashType(CREATE_NEIGHBOUR_SUBSCRIPTIONS));
-			System.out.println("Creating outstandingBatches table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating outstandingBatches table");
 			s.executeUpdate(insertHashType(CREATE_OUTSTANDING_BATCHES));
-			System.out.println("Creating outstandingMessages table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating outstandingMessages table");
 			s.executeUpdate(insertHashType(CREATE_OUTSTANDING_MESSAGES));
 			s.executeUpdate(INDEX_OUTSTANDING_MESSAGES_BY_BATCH);
-			System.out.println("Creating ratings table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating ratings table");
 			s.executeUpdate(insertHashType(CREATE_RATINGS));
-			System.out.println("Creating receivedBundles table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating receivedBundles table");
 			s.executeUpdate(insertHashType(CREATE_RECEIVED_BUNDLES));
-			System.out.println("Creating statuses table");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine("Creating statuses table");
 			s.executeUpdate(insertHashType(CREATE_STATUSES));
 			s.executeUpdate(INDEX_STATUSES_BY_MESSAGE);
 			s.executeUpdate(INDEX_STATUSES_BY_NEIGHBOUR);
@@ -268,7 +281,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 				assert txn != null;
 				synchronized(connections) {
 					openConnections++;
-					System.out.println(openConnections + " open connections");
+					if(LOG.isLoggable(Level.FINE))
+						LOG.fine(openConnections + " open connections");
 				}
 			}
 			txn.setAutoCommit(false);
@@ -313,7 +327,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 			openConnections -= connections.size();
 			connections.clear();
 			while(openConnections > 0) {
-				System.out.println("Waiting for " + openConnections
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Waiting for " + openConnections
 						+ " open connections");
 				try {
 					connections.wait();
@@ -810,8 +825,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 			}
 			rs.close();
 			ps.close();
-			System.out.println(ids.size() + " old messages, " + total
-					+ " bytes");
+			if(LOG.isLoggable(Level.FINE))
+				LOG.fine(ids.size() + " old messages, " + total + " bytes");
 			return ids;
 		} catch(SQLException e) {
 			tryToClose(rs);
@@ -920,7 +935,8 @@ abstract class JdbcDatabase implements Database<Connection> {
 			rs.close();
 			ps.close();
 			if(!ids.isEmpty()) {
-				System.out.println(ids.size() + " sendable messages, " + total
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine(ids.size() + " sendable messages, " + total
 						+ " bytes");
 			}
 			return ids;
diff --git a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
index 1b5f7b1001..51d6244969 100644
--- a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
+++ b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java
@@ -4,6 +4,8 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.NeighbourId;
@@ -22,6 +24,9 @@ import com.google.inject.Provider;
 
 class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 
+	private static final Logger LOG =
+		Logger.getLogger(ReadWriteLockDatabaseComponent.class.getName());
+
 	/*
 	 * Locks must always be acquired in alphabetical order. See the Database
 	 * interface to find out which calls require which locks. Note: this
@@ -91,7 +96,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void addNeighbour(NeighbourId n) throws DbException {
-		System.out.println("Adding neighbour " + n);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding neighbour " + n);
 		neighbourLock.writeLock().lock();
 		try {
 			Txn txn = db.startTransaction("addNeighbour");
@@ -121,7 +126,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 							boolean added = storeMessage(txn, m, null);
 							assert added;
 						} else {
-							System.out.println("Not subscribed");
+							if(LOG.isLoggable(Level.FINE))
+								LOG.fine("Not subscribed");
 						}
 						db.commitTransaction(txn);
 					} catch(DbException e) {
@@ -201,7 +207,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void subscribe(GroupId g) throws DbException {
-		System.out.println("Subscribing to " + g);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Subscribing to " + g);
 		subscriptionLock.writeLock().lock();
 		try {
 			Txn txn = db.startTransaction("subscribe");
@@ -218,7 +224,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void unsubscribe(GroupId g) throws DbException {
-		System.out.println("Unsubscribing from " + g);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Unsubscribing from " + g);
 		messageLock.writeLock().lock();
 		try {
 			neighbourLock.writeLock().lock();
@@ -245,7 +251,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void generateBundle(NeighbourId n, Bundle b) throws DbException {
-		System.out.println("Generating bundle for " + n);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Generating bundle for " + n);
 		// Ack all batches received from the neighbour
 		neighbourLock.writeLock().lock();
 		try {
@@ -256,7 +262,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					b.addAck(ack);
 					numAcks++;
 				}
-				System.out.println("Added " + numAcks + " acks");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Added " + numAcks + " acks");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -275,7 +282,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					b.addSubscription(g);
 					numSubs++;
 				}
-				System.out.println("Added " + numSubs + " subscriptions");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Added " + numSubs + " subscriptions");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -296,7 +304,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 			if(batch.getSize() * 2 < Batch.CAPACITY) break;
 		}
 		b.seal();
-		System.out.println("Bundle sent, " + b.getSize() + " bytes");
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Bundle sent, " + b.getSize() + " bytes");
 		System.gc();
 	}
 
@@ -354,7 +363,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void receiveBundle(NeighbourId n, Bundle b) throws DbException {
-		System.out.println("Received bundle from " + n + ", "
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Received bundle from " + n + ", "
 				+ b.getSize() + " bytes");
 		// Mark all messages in acked batches as seen
 		messageLock.readLock().lock();
@@ -384,7 +394,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 						throw e;
 					}
 				}
-				System.out.println("Received " + acks + " acks, " + expired
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Received " + acks + " acks, " + expired
 						+ " expired");
 			} finally {
 				neighbourLock.writeLock().unlock();
@@ -403,7 +414,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					subs++;
 					db.addSubscription(txn, n, g);
 				}
-				System.out.println("Received " + subs + " subscriptions");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Received " + subs + " subscriptions");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -432,7 +444,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 									if(storeMessage(txn, m, n)) stored++;
 								}
 							}
-							System.out.println("Received " + received
+							if(LOG.isLoggable(Level.FINE))
+								LOG.fine("Received " + received
 									+ " messages, stored " + stored);
 							db.addBatchToAck(txn, n, batch.getId());
 							db.commitTransaction(txn);
@@ -450,7 +463,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 				messageLock.writeLock().unlock();
 			}
 		}
-		System.out.println("Received " + batches + " batches");
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Received " + batches + " batches");
 		// Find any lost batches that need to be retransmitted
 		Set<BatchId> lost;
 		messageLock.readLock().lock();
@@ -478,7 +492,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 				try {
 					Txn txn = db.startTransaction("receiveBundle:removeLost");
 					try {
-						System.out.println("Removing lost batch");
+						if(LOG.isLoggable(Level.FINE))
+							LOG.fine("Removing lost batch");
 						db.removeLostBatch(txn, n, batch);
 						db.commitTransaction(txn);
 					} catch(DbException e) {
diff --git a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
index b73af7a1ac..9dff747804 100644
--- a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
+++ b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java
@@ -3,9 +3,8 @@ package net.sf.briar.db;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
-
-import com.google.inject.Inject;
-import com.google.inject.Provider;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import net.sf.briar.api.db.DbException;
 import net.sf.briar.api.db.NeighbourId;
@@ -19,8 +18,14 @@ import net.sf.briar.api.protocol.GroupId;
 import net.sf.briar.api.protocol.Message;
 import net.sf.briar.api.protocol.MessageId;
 
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
 class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 
+	private static final Logger LOG =
+		Logger.getLogger(SynchronizedDatabaseComponent.class.getName());
+
 	/*
 	 * Locks must always be acquired in alphabetical order. See the Database
 	 * interface to find out which calls require which locks.
@@ -67,7 +72,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void addNeighbour(NeighbourId n) throws DbException {
-		System.out.println("Adding neighbour " + n);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding neighbour " + n);
 		synchronized(neighbourLock) {
 			Txn txn = db.startTransaction("addNeighbour");
 			try {
@@ -91,7 +96,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 							boolean added = storeMessage(txn, m, null);
 							assert added;
 						} else {
-							System.out.println("Not subscribed");
+							if(LOG.isLoggable(Level.FINE))
+								LOG.fine("Not subscribed");
 						}
 						db.commitTransaction(txn);
 					} catch(DbException e) {
@@ -153,7 +159,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void subscribe(GroupId g) throws DbException {
-		System.out.println("Subscribing to " + g);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Subscribing to " + g);
 		synchronized(subscriptionLock) {
 			Txn txn = db.startTransaction("subscribe");
 			try {
@@ -167,7 +173,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void unsubscribe(GroupId g) throws DbException {
-		System.out.println("Unsubscribing from " + g);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Unsubscribing from " + g);
 		synchronized(messageLock) {
 			synchronized(neighbourLock) {
 				synchronized(subscriptionLock) {
@@ -185,7 +191,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void generateBundle(NeighbourId n, Bundle b) throws DbException {
-		System.out.println("Generating bundle for " + n);
+		if(LOG.isLoggable(Level.FINE)) LOG.fine("Generating bundle for " + n);
 		// Ack all batches received from the neighbour
 		synchronized(neighbourLock) {
 			Txn txn = db.startTransaction("generateBundle:acks");
@@ -195,7 +201,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					b.addAck(ack);
 					numAcks++;
 				}
-				System.out.println("Added " + numAcks + " acks");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Added " + numAcks + " acks");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -211,7 +218,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					b.addSubscription(g);
 					numSubs++;
 				}
-				System.out.println("Added " + numSubs + " subscriptions");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Added " + numSubs + " subscriptions");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -230,7 +238,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 			if(batch.getSize() * 2 < Batch.CAPACITY) break;
 		}
 		b.seal();
-		System.out.println("Bundle sent, " + b.getSize() + " bytes");
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Bundle sent, " + b.getSize() + " bytes");
 		System.gc();
 	}
 
@@ -268,7 +277,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 	}
 
 	public void receiveBundle(NeighbourId n, Bundle b) throws DbException {
-		System.out.println("Received bundle from " + n + ", "
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Received bundle from " + n + ", "
 				+ b.getSize() + " bytes");
 		// Mark all messages in acked batches as seen
 		synchronized(messageLock) {
@@ -296,7 +306,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 						throw e;
 					}
 				}
-				System.out.println("Received " + acks + " acks, " + expired
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Received " + acks + " acks, " + expired
 						+ " expired");
 			}
 		}
@@ -310,7 +321,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 					subs++;
 					db.addSubscription(txn, n, g);
 				}
-				System.out.println("Received " + subs + " subscriptions");
+				if(LOG.isLoggable(Level.FINE))
+					LOG.fine("Received " + subs + " subscriptions");
 				db.commitTransaction(txn);
 			} catch(DbException e) {
 				db.abortTransaction(txn);
@@ -334,7 +346,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 									if(storeMessage(txn, m, n)) stored++;
 								}
 							}
-							System.out.println("Received " + received
+							if(LOG.isLoggable(Level.FINE))
+								LOG.fine("Received " + received
 									+ " messages, stored " + stored);
 							db.addBatchToAck(txn, n, batch.getId());
 							db.commitTransaction(txn);
@@ -346,7 +359,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 				}
 			}
 		}
-		System.out.println("Received " + batches + " batches");
+		if(LOG.isLoggable(Level.FINE))
+			LOG.fine("Received " + batches + " batches");
 		// Find any lost batches that need to be retransmitted
 		Set<BatchId> lost;
 		synchronized(messageLock) {
@@ -366,7 +380,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
 				synchronized(neighbourLock) {
 					Txn txn = db.startTransaction("receiveBundle:removeLost");
 					try {
-						System.out.println("Removing lost batch");
+						if(LOG.isLoggable(Level.FINE))
+							LOG.fine("Removing lost batch");
 						db.removeLostBatch(txn, n, batch);
 						db.commitTransaction(txn);
 					} catch(DbException e) {
diff --git a/components/net/sf/briar/protocol/BatchImpl.java b/components/net/sf/briar/protocol/BatchImpl.java
index a6c5eb4a6a..be84a7594f 100644
--- a/components/net/sf/briar/protocol/BatchImpl.java
+++ b/components/net/sf/briar/protocol/BatchImpl.java
@@ -15,7 +15,7 @@ class BatchImpl implements Batch {
 	private long size = 0L;
 
 	public void seal() {
-		System.out.println("FIXME: Calculate batch ID");
+		// FIXME: Calculate batch ID
 		byte[] b = new byte[BatchId.LENGTH];
 		new Random().nextBytes(b);
 		id = new BatchId(b);
diff --git a/test/net/sf/briar/util/FileUtilsTest.java b/test/net/sf/briar/util/FileUtilsTest.java
index 94fe9476e3..0f303d56c1 100644
--- a/test/net/sf/briar/util/FileUtilsTest.java
+++ b/test/net/sf/briar/util/FileUtilsTest.java
@@ -121,6 +121,43 @@ public class FileUtilsTest extends TestCase {
 		assertEquals("three three three".length(), dest3.length());
 	}
 
+	@Test
+	public void testDeleteFile() throws IOException {
+		File foo = new File(testDir, "foo");
+		foo.createNewFile();
+		assertTrue(foo.exists());
+
+		FileUtils.delete(foo);
+
+		assertFalse(foo.exists());
+	}
+
+	@Test
+	public void testDeleteDirectory() throws IOException {
+		File f1 = new File(testDir, "abc/def/1");
+		File f2 = new File(testDir, "abc/def/2");
+		File f3 = new File(testDir, "abc/3");
+		File abc = new File(testDir, "abc");
+		File def = new File(testDir, "abc/def");
+		TestUtils.createFile(f1, "one one one");
+		TestUtils.createFile(f2, "two two two");
+		TestUtils.createFile(f3, "three three three");
+
+		assertTrue(f1.exists());
+		assertTrue(f2.exists());
+		assertTrue(f3.exists());
+		assertTrue(abc.exists());
+		assertTrue(def.exists());
+
+		FileUtils.delete(def);
+
+		assertFalse(f1.exists());
+		assertFalse(f2.exists());
+		assertTrue(f3.exists());
+		assertTrue(abc.exists());
+		assertFalse(def.exists());
+	}
+
 	@After
 	public void tearDown() throws IOException {
 		TestUtils.delete(testDir);
diff --git a/util/net/sf/briar/util/FileUtils.java b/util/net/sf/briar/util/FileUtils.java
index f86d5eaa5d..7475713892 100644
--- a/util/net/sf/briar/util/FileUtils.java
+++ b/util/net/sf/briar/util/FileUtils.java
@@ -84,6 +84,11 @@ public class FileUtils {
 		}
 	}
 
+	public static void delete(File f) {
+		if(f.isDirectory()) for(File child : f.listFiles()) delete(child);
+		f.delete();
+	}
+
 	public interface Callback {
 
 		void processingFile(File f);
-- 
GitLab