From 38ed9d69bfe45ca804a6391d744ebf600bd2d959 Mon Sep 17 00:00:00 2001
From: akwizgran <michael@briarproject.org>
Date: Wed, 31 Oct 2012 14:26:59 +0000
Subject: [PATCH] Wrap java.util.Timer in an interface so it can be mocked.

---
 src/net/sf/briar/api/clock/SystemTimer.java   | 29 +++++++++++++++++++
 src/net/sf/briar/api/clock/Timer.java         | 27 +++++++++++++++++
 .../sf/briar/api/crypto/MessageDigest.java    |  5 +++-
 src/net/sf/briar/clock/ClockModule.java       |  3 ++
 src/net/sf/briar/db/DatabaseCleanerImpl.java  | 14 ++++++---
 .../sf/briar/transport/KeyManagerImpl.java    |  6 ++--
 6 files changed, 76 insertions(+), 8 deletions(-)
 create mode 100644 src/net/sf/briar/api/clock/SystemTimer.java
 create mode 100644 src/net/sf/briar/api/clock/Timer.java

diff --git a/src/net/sf/briar/api/clock/SystemTimer.java b/src/net/sf/briar/api/clock/SystemTimer.java
new file mode 100644
index 0000000000..b220e3026b
--- /dev/null
+++ b/src/net/sf/briar/api/clock/SystemTimer.java
@@ -0,0 +1,29 @@
+package net.sf.briar.api.clock;
+
+import java.util.TimerTask;
+
+/** Default timer implementation. */
+public class SystemTimer implements Timer {
+
+	private final java.util.Timer timer = new java.util.Timer();
+
+	public void cancel() {
+		timer.cancel();
+	}
+
+	public int purge() {
+		return timer.purge();
+	}
+
+	public void schedule(TimerTask task, long delay) {
+		timer.schedule(task, delay);
+	}
+
+	public void schedule(TimerTask task, long delay, long period) {
+		timer.schedule(task, delay, period);
+	}
+
+	public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
+		timer.scheduleAtFixedRate(task, delay, period);
+	}
+}
diff --git a/src/net/sf/briar/api/clock/Timer.java b/src/net/sf/briar/api/clock/Timer.java
new file mode 100644
index 0000000000..9e5cae3213
--- /dev/null
+++ b/src/net/sf/briar/api/clock/Timer.java
@@ -0,0 +1,27 @@
+package net.sf.briar.api.clock;
+
+import java.util.TimerTask;
+
+/**
+ * A wrapper around a {@link java.util.Timer} that allows it to be replaced for
+ * testing.
+ */
+public interface Timer {
+
+	/** @see {@link java.util.Timer#cancel()} */
+	void cancel();
+
+	/** @see {@link java.util.Timer#purge()} */
+	int purge();
+
+	/** @see {@link java.util.Timer#schedule(TimerTask, long)} */
+	void schedule(TimerTask task, long delay);
+
+	/** @see {@link java.util.Timer#schedule(TimerTask, long, long)} */
+	void schedule(TimerTask task, long delay, long period);
+
+	/**
+	 * @see {@link java.util.Timer#scheduleAtFixedRate(TimerTask, long, long)}
+	 */
+	void scheduleAtFixedRate(TimerTask task, long delay, long period);
+}
diff --git a/src/net/sf/briar/api/crypto/MessageDigest.java b/src/net/sf/briar/api/crypto/MessageDigest.java
index 641bf8d0fc..3855da8929 100644
--- a/src/net/sf/briar/api/crypto/MessageDigest.java
+++ b/src/net/sf/briar/api/crypto/MessageDigest.java
@@ -1,6 +1,9 @@
 package net.sf.briar.api.crypto;
 
-/** An interface that allows a java.security.MessageDigest to be wrapped. */
+/**
+ * A wrapper around a {@link java.security.MessageDigest} that allows it to be
+ * replaced for testing.
+ */
 public interface MessageDigest {
 
 	/** @see {@link java.security.MessageDigest#digest()} */
diff --git a/src/net/sf/briar/clock/ClockModule.java b/src/net/sf/briar/clock/ClockModule.java
index f394211cc3..8bf9a3816d 100644
--- a/src/net/sf/briar/clock/ClockModule.java
+++ b/src/net/sf/briar/clock/ClockModule.java
@@ -2,6 +2,8 @@ package net.sf.briar.clock;
 
 import net.sf.briar.api.clock.Clock;
 import net.sf.briar.api.clock.SystemClock;
+import net.sf.briar.api.clock.SystemTimer;
+import net.sf.briar.api.clock.Timer;
 
 import com.google.inject.AbstractModule;
 
@@ -10,5 +12,6 @@ public class ClockModule extends AbstractModule {
 	@Override
 	protected void configure() {
 		bind(Clock.class).to(SystemClock.class);
+		bind(Timer.class).to(SystemTimer.class);
 	}
 }
diff --git a/src/net/sf/briar/db/DatabaseCleanerImpl.java b/src/net/sf/briar/db/DatabaseCleanerImpl.java
index 6c0673068b..4b22fcdecb 100644
--- a/src/net/sf/briar/db/DatabaseCleanerImpl.java
+++ b/src/net/sf/briar/db/DatabaseCleanerImpl.java
@@ -3,29 +3,35 @@ package net.sf.briar.db;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
 
-import java.util.Timer;
 import java.util.TimerTask;
 import java.util.logging.Logger;
 
+import net.sf.briar.api.clock.Timer;
 import net.sf.briar.api.db.DbClosedException;
 import net.sf.briar.api.db.DbException;
 
+import com.google.inject.Inject;
+
 class DatabaseCleanerImpl extends TimerTask implements DatabaseCleaner {
 
 	private static final Logger LOG =
 			Logger.getLogger(DatabaseCleanerImpl.class.getName());
 
+	private final Timer timer;
+
 	private volatile Callback callback = null;
-	private volatile Timer timer = null;
+
+	@Inject
+	DatabaseCleanerImpl(Timer timer) {
+		this.timer = timer;
+	}
 
 	public void startCleaning(Callback callback, long msBetweenSweeps) {
 		this.callback = callback;
-		timer = new Timer();
 		timer.scheduleAtFixedRate(this, 0L, msBetweenSweeps);
 	}
 
 	public void stopCleaning() {
-		if(timer == null) throw new IllegalStateException();
 		timer.cancel();
 	}
 
diff --git a/src/net/sf/briar/transport/KeyManagerImpl.java b/src/net/sf/briar/transport/KeyManagerImpl.java
index 6ff240356b..39b4175abc 100644
--- a/src/net/sf/briar/transport/KeyManagerImpl.java
+++ b/src/net/sf/briar/transport/KeyManagerImpl.java
@@ -8,11 +8,11 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Timer;
 import java.util.TimerTask;
 import java.util.logging.Logger;
 
 import net.sf.briar.api.ContactId;
+import net.sf.briar.api.clock.Timer;
 import net.sf.briar.api.crypto.CryptoComponent;
 import net.sf.briar.api.crypto.KeyManager;
 import net.sf.briar.api.db.DatabaseComponent;
@@ -49,11 +49,11 @@ class KeyManagerImpl extends TimerTask implements KeyManager, DatabaseListener {
 
 	@Inject
 	public KeyManagerImpl(CryptoComponent crypto, DatabaseComponent db,
-			ConnectionRecogniser recogniser) {
+			ConnectionRecogniser recogniser, Timer timer) {
 		this.crypto = crypto;
 		this.db = db;
 		this.recogniser = recogniser;
-		timer = new Timer();
+		this.timer = timer;
 		outgoing = new HashMap<ContactTransportKey, TemporarySecret>();
 		incomingOld = new HashMap<ContactTransportKey, TemporarySecret>();
 		incomingNew = new HashMap<ContactTransportKey, TemporarySecret>();
-- 
GitLab