add continuous callback
authorDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Tue, 15 Apr 2008 23:15:49 +0000 (23:15 +0000)
committerDavid ‘Bombe’ Roden <bombe@freenetproject.org>
Tue, 15 Apr 2008 23:15:49 +0000 (23:15 +0000)
git-svn-id: http://trooper/svn/projects/jFCPlib/branch/high-level-client@836 c3eda9e8-030b-0410-8277-bc7414b0a119

src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java [new file with mode: 0644]
src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java [new file with mode: 0644]
src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java [new file with mode: 0644]

diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java
new file mode 100644 (file)
index 0000000..4f82b70
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * jFCPlib-high-level-client - HighLevelContinousCallback.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Callback for an operation that sends progress messages before completion.
+ * 
+ * @param <R>
+ *            The type of the continuous result
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ * @version $Id$
+ */
+public class HighLevelContinuousCallback<R extends HighLevelContinuousResult> extends HighLevelCallback<R> {
+
+       /** Callback listeners. */
+       private final List<HighLevelContinuousCallbackListener<R>> highLevelContinuousCallbackListeners = new ArrayList<HighLevelContinuousCallbackListener<R>>();
+
+       /** List of progress results. */
+       private final List<R> progressQueue = new ArrayList<R>();
+
+       /**
+        * Creates a new continuous callback with the given result.
+        * 
+        * @see HighLevelCallback#HighLevelCallback(HighLevelResult)
+        * @param progress
+        *            The result of the operation
+        */
+       HighLevelContinuousCallback(R progress) {
+               super(progress);
+       }
+
+       //
+       // EVENT MANAGEMENT
+       //
+
+       /**
+        * Adds a callback listener to this callback. If this callback already has
+        * some progress results, the listener is notified immediately.
+        * 
+        * @param highLevelContinuousCallbackListener
+        *            The callback listener to add
+        */
+       public void addHighLevelContinuousCallbackListener(HighLevelContinuousCallbackListener<R> highLevelContinuousCallbackListener) {
+               highLevelContinuousCallbackListeners.add(highLevelContinuousCallbackListener);
+               synchronized (progressQueue) {
+                       if (!progressQueue.isEmpty()) {
+                               fireGotProgress();
+                       }
+               }
+       }
+
+       /**
+        * Removes a callback listener from this callback.
+        * 
+        * @param highLevelContinuousCallbackListener
+        *            The callback listener to remove
+        */
+       public void removeHighLevelContinuousCallbackListener(HighLevelContinuousCallbackListener<R> highLevelContinuousCallbackListener) {
+               highLevelContinuousCallbackListeners.remove(highLevelContinuousCallbackListener);
+       }
+
+       /**
+        * Notifies all listeners that progress results have been received.
+        */
+       private void fireGotProgress() {
+               for (HighLevelContinuousCallbackListener<R> highLevelContinuousCallbackListener: highLevelContinuousCallbackListeners) {
+                       highLevelContinuousCallbackListener.gotProgress(this);
+               }
+       }
+
+       //
+       // ACCESSORS
+       //
+
+       /**
+        * Returns the next progress result and removes it from the queue. If no
+        * progress result is yet available, this method will block.
+        * 
+        * @return The next progress result
+        * @throws InterruptedException
+        *             if {@link Object#wait()} is interrupted
+        */
+       public R getProgress() throws InterruptedException {
+               return getProgress(0);
+       }
+
+       /**
+        * Returns the next progress result and removes it from the queue. If no
+        * progress result is yet available, this method will block until either a
+        * progress result is available or the given time (in milliseconds) has
+        * passed.
+        * 
+        * @param waitTime
+        *            The maximum time to wait for a progress result
+        * @return The next progress result
+        * @throws InterruptedException
+        *             if {@link Object#wait()} is interrupted
+        */
+       public R getProgress(long waitTime) throws InterruptedException {
+               synchronized (progressQueue) {
+                       if (progressQueue.isEmpty()) {
+                               progressQueue.wait(waitTime);
+                       }
+                       return progressQueue.remove(0);
+               }
+       }
+
+       /**
+        * Returns the latest progress result and clears the queue.
+        * 
+        * @return The latest progress result, or <code>null</code> if the queue
+        *         is empty
+        */
+       public R getLatestProgress() {
+               synchronized (progressQueue) {
+                       if (progressQueue.isEmpty()) {
+                               return null;
+                       }
+                       R latestProgress = progressQueue.get(progressQueue.size() - 1);
+                       progressQueue.clear();
+                       return latestProgress;
+               }
+       }
+
+       /**
+        * Adds a progress result and notifies all listeners.
+        * 
+        * @param progress
+        *            The progress result to add
+        */
+       void addProgress(R progress) {
+               synchronized (progressQueue) {
+                       progressQueue.add(progress);
+                       progressQueue.notify();
+               }
+               fireGotProgress();
+       }
+
+}
diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java
new file mode 100644 (file)
index 0000000..09636bc
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * jFCPlib-high-level-client - HighLevelContinuousCallbackListener.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+/**
+ * Interface for objects that want to be notified as soon as a lengthy operation
+ * made some progress.
+ * 
+ * @param <R>
+ *            The type of the progress result
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ * @version $Id$
+ */
+public interface HighLevelContinuousCallbackListener<R extends HighLevelContinuousResult> extends HighLevelCallbackListener<R> {
+
+       /**
+        * Notifies a listener that a progress message has been received.
+        * 
+        * @param highLevelContinuousCallback
+        *            The callback that made the progress
+        */
+       public void gotProgress(HighLevelContinuousCallback<R> highLevelContinuousCallback);
+
+}
diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java
new file mode 100644 (file)
index 0000000..397b4a9
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * jFCPlib-high-level-client - HighLevelContinuosResult.java -
+ * Copyright © 2008 David Roden
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+package net.pterodactylus.fcp.highlevel;
+
+/**
+ * Result for operations that send progress messages until they have completed.
+ * 
+ * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
+ * @version $Id$
+ */
+public abstract class HighLevelContinuousResult extends HighLevelResult {
+
+       /** The number of total blocks. */
+       private int totalBlocks;
+
+       /** The number of required blocks. */
+       private int requiredBlocks;
+
+       /** The number of successfully transferred blocks. */
+       private int successfulBlocks;
+
+       /** The number of failed blocks. */
+       private int failedBlocks;
+
+       /** The number of fatally failed blocks. */
+       private int fatallyFailedBlocks;
+
+       /** Whether the total number is finalized. */
+       private boolean totalFinalized;
+
+       /**
+        * Returns the number of total blocks.
+        * 
+        * @return The number of total blocks
+        */
+       public int getTotalBlocks() {
+               return totalBlocks;
+       }
+
+       /**
+        * Sets the number of total blocks.
+        * 
+        * @param totalBlocks
+        *            The number of total blocks
+        */
+       void setTotalBlocks(int totalBlocks) {
+               this.totalBlocks = totalBlocks;
+       }
+
+       /**
+        * Returns the number of required blocks. For downloads, this number is
+        * smaller than {@link #getTotalBlocks()}.
+        * 
+        * @return The number of required blocks
+        */
+       public int getRequiredBlocks() {
+               return requiredBlocks;
+       }
+
+       /**
+        * Sets the number of required blocks.
+        * 
+        * @param requiredBlocks
+        *            The number of required blocks
+        */
+       void setRequiredBlocks(int requiredBlocks) {
+               this.requiredBlocks = requiredBlocks;
+       }
+
+       /**
+        * Returns the number of successfully transferred blocks.
+        * 
+        * @return The number of successfully transferred blocks
+        */
+       public int getSuccessfulBlocks() {
+               return successfulBlocks;
+       }
+
+       /**
+        * Sets the number of successfully transferred blocks.
+        * 
+        * @param successfulBlocks
+        *            The number of successfully transferred blocks
+        */
+       void setSuccessfulBlocks(int successfulBlocks) {
+               this.successfulBlocks = successfulBlocks;
+       }
+
+       /**
+        * Returns the number of failed blocks. Blocks that have failed can be
+        * retried.
+        * 
+        * @return The number of failed blocks
+        */
+       public int getFailedBlocks() {
+               return failedBlocks;
+       }
+
+       /**
+        * Sets the number of failed blocks.
+        * 
+        * @param failedBlocks
+        *            The number of failed blocks
+        */
+       void setFailedBlocks(int failedBlocks) {
+               this.failedBlocks = failedBlocks;
+       }
+
+       /**
+        * Returns the number of fatally failed blocks. Fatally failed blocks will
+        * never complete, even with endless retries.
+        * 
+        * @return The number of fatally failed blocks
+        */
+       public int getFatallyFailedBlocks() {
+               return fatallyFailedBlocks;
+       }
+
+       /**
+        * Sets the number of fatally failed blocks.
+        * 
+        * @param fatallyFailedBlocks
+        *            The number fatally failed blocks
+        */
+       void setFatallyFailedBlocks(int fatallyFailedBlocks) {
+               this.fatallyFailedBlocks = fatallyFailedBlocks;
+       }
+
+       /**
+        * Returns whether the result of {@link #getTotalBlocks()} is final, i.e. it
+        * won’t change anymore.
+        * 
+        * @return <code>true</code> if the result of {@link #getTotalBlocks()} is
+        *         final, <code>false</code> otherwise
+        */
+       public boolean isTotalFinalized() {
+               return totalFinalized;
+       }
+
+       /**
+        * Sets whether the result of {@link #getTotalBlocks()} is final, i.e. it
+        * won’t change anymore.
+        * 
+        * @param totalFinalized
+        *            <code>true</code> if the result of {@link #getTotalBlocks()}
+        *            is final, <code>false</code> otherwise
+        */
+       void setTotalFinalized(boolean totalFinalized) {
+               this.totalFinalized = totalFinalized;
+       }
+
+}