Whitespace and formatting fixes.
[jFCPlib.git] / src / net / pterodactylus / fcp / highlevel / HighLevelCallback.java
index 304d24e..7dc55df 100644 (file)
@@ -30,18 +30,30 @@ import java.util.List;
  * @param <R>
  *            The type of the high-level operation result
  * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
- * @version $Id$
  */
 public class HighLevelCallback<R extends HighLevelResult> {
 
        /** Object used for synchronization. */
-       public final Object syncObject = new Object();
+       protected final Object syncObject = new Object();
 
        /** The list of callback listeners. */
-       public final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
+       private final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
+
+       /** Whether the result is complete. */
+       protected boolean resultComplete = false;
 
        /** The result of the operation. */
-       public R result = null;
+       private R result = null;
+
+       /**
+        * Package-private construtor.
+        * 
+        * @param result
+        *            The result of the operation
+        */
+       HighLevelCallback(R result) {
+               this.result = result;
+       }
 
        /**
         * Adds a callback listener to this callback. The callback listener will be
@@ -71,15 +83,17 @@ public class HighLevelCallback<R extends HighLevelResult> {
        }
 
        /**
-        * Notifies all listeners that the result of the operation is now known.
+        * Notifies all listeners that the result of the operation is now known. As
+        * soon as a listener was notified it will be removed from the list of
+        * listeners!
         * 
         * @see HighLevelCallbackListener#gotResult(HighLevelCallback)
         */
        private synchronized void fireGotResult() {
                for (HighLevelCallbackListener<R> highLevelCallbackListener: highLevelCallbackListeners) {
-                       highLevelCallbackListeners.remove(highLevelCallbackListener);
                        highLevelCallbackListener.gotResult(this);
                }
+               highLevelCallbackListeners.clear();
        }
 
        /**
@@ -91,7 +105,7 @@ public class HighLevelCallback<R extends HighLevelResult> {
         */
        public boolean isDone() {
                synchronized (syncObject) {
-                       return result != null;
+                       return resultComplete;
                }
        }
 
@@ -120,7 +134,7 @@ public class HighLevelCallback<R extends HighLevelResult> {
         */
        public R getResult(long waitTime) throws InterruptedException {
                synchronized (syncObject) {
-                       if (result == null) {
+                       while (!resultComplete) {
                                syncObject.wait(waitTime);
                        }
                        return result;
@@ -128,16 +142,26 @@ public class HighLevelCallback<R extends HighLevelResult> {
        }
 
        /**
-        * Sets the result of the operation. Calling this method will result in all
-        * listeners being notified.
+        * Returns the result even if it is not yet complete.
         * 
-        * @see #fireGotResult()
-        * @param result
-        *            The result of the operation
+        * @return The result of the operation
         */
-       void setResult(R result) {
+       R getIntermediaryResult() {
                synchronized (syncObject) {
-                       this.result = result;
+                       return result;
+               }
+       }
+
+       /**
+        * Marks the result as complete and notify the listeners. If the result was
+        * already complete, nothing will be done.
+        */
+       void setDone() {
+               synchronized (syncObject) {
+                       if (resultComplete) {
+                               return;
+                       }
+                       resultComplete = true;
                        syncObject.notifyAll();
                }
                fireGotResult();