Add support for IFutureSPFResultListener. See JSPF-94
git-svn-id: https://svn.apache.org/repos/asf/james/jspf/trunk@1202747 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/resolver/src/main/java/org/apache/james/jspf/executor/FutureSPFResult.java b/resolver/src/main/java/org/apache/james/jspf/executor/FutureSPFResult.java
index 687d6be..2733bdf 100644
--- a/resolver/src/main/java/org/apache/james/jspf/executor/FutureSPFResult.java
+++ b/resolver/src/main/java/org/apache/james/jspf/executor/FutureSPFResult.java
@@ -19,6 +19,9 @@
package org.apache.james.jspf.executor;
+import java.util.ArrayList;
+import java.util.List;
+
import org.apache.james.jspf.core.SPFSession;
@@ -29,6 +32,8 @@
public class FutureSPFResult extends SPFResult {
private boolean isReady;
+ private List<IFutureSPFResultListener> listeners;
+ private int waiters;
public FutureSPFResult() {
isReady = false;
@@ -41,9 +46,21 @@
*
*/
public synchronized void setSPFResult(SPFSession session) {
- setSPFSession(session);
- isReady = true;
- notify();
+ if (!isReady) {
+ setSPFSession(session);
+ isReady = true;
+ if (waiters > 0) {
+ notifyAll();
+ }
+ if (listeners != null) {
+ for (IFutureSPFResultListener listener : listeners) {
+ listener.onSPFResult(this);
+ }
+ }
+ listeners = null;
+ }
+
+
}
/**
@@ -53,9 +70,13 @@
private synchronized void checkReady() {
while (!isReady) {
try {
+ waiters++;
wait();
} catch (InterruptedException e) {
- //
+ //
+ Thread.interrupted();
+ } finally {
+ waiters--;
}
}
}
@@ -108,4 +129,47 @@
public synchronized boolean isReady() {
return isReady;
}
+
+ /**
+ * Add a {@link IFutureSPFResultListener} which will get notified once {@link #isReady()} returns <code>true</code>
+ *
+ * @param listener
+ */
+ public synchronized void addListener(IFutureSPFResultListener listener) {
+ if (!isReady) {
+ if (listeners == null) {
+ listeners = new ArrayList<IFutureSPFResultListener>();
+ }
+ listeners.add(listener);
+ } else {
+ listener.onSPFResult(this);
+ }
+ }
+
+ /**
+ * Remove a {@link IFutureSPFResultListener}
+ *
+ * @param listener
+ */
+ public synchronized void removeListener(IFutureSPFResultListener listener) {
+ if (listeners != null) {
+ listeners.remove(listener);
+ }
+ }
+
+
+ /**
+ * Listener which will get notified once a {@link FutureSPFResult#isReady()} returns <code>true</code>. So it will not block anymore
+ *
+ *
+ */
+ public interface IFutureSPFResultListener {
+
+ /**
+ * Get called once a {@link FutureSPFResult} is ready
+ *
+ * @param result
+ */
+ void onSPFResult(FutureSPFResult result);
+ }
}