From 9c4446f8be561fac93443cb07b45f756436788ac Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Tue, 15 Apr 2008 23:15:49 +0000 Subject: [PATCH] add continuous callback git-svn-id: http://trooper/svn/projects/jFCPlib/branch/high-level-client@836 c3eda9e8-030b-0410-8277-bc7414b0a119 --- .../fcp/highlevel/HighLevelContinuousCallback.java | 159 +++++++++++++++++++ .../HighLevelContinuousCallbackListener.java | 41 +++++ .../fcp/highlevel/HighLevelContinuousResult.java | 169 +++++++++++++++++++++ 3 files changed, 369 insertions(+) create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java new file mode 100644 index 0000000..4f82b70 --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java @@ -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 + * The type of the continuous result + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class HighLevelContinuousCallback extends HighLevelCallback { + + /** Callback listeners. */ + private final List> highLevelContinuousCallbackListeners = new ArrayList>(); + + /** List of progress results. */ + private final List progressQueue = new ArrayList(); + + /** + * 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 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 highLevelContinuousCallbackListener) { + highLevelContinuousCallbackListeners.remove(highLevelContinuousCallbackListener); + } + + /** + * Notifies all listeners that progress results have been received. + */ + private void fireGotProgress() { + for (HighLevelContinuousCallbackListener 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 null 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 index 0000000..09636bc --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java @@ -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 + * The type of the progress result + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public interface HighLevelContinuousCallbackListener extends HighLevelCallbackListener { + + /** + * Notifies a listener that a progress message has been received. + * + * @param highLevelContinuousCallback + * The callback that made the progress + */ + public void gotProgress(HighLevelContinuousCallback highLevelContinuousCallback); + +} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java new file mode 100644 index 0000000..397b4a9 --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java @@ -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 <bombe@freenetproject.org> + * @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 true if the result of {@link #getTotalBlocks()} is + * final, false otherwise + */ + public boolean isTotalFinalized() { + return totalFinalized; + } + + /** + * Sets whether the result of {@link #getTotalBlocks()} is final, i.e. it + * won’t change anymore. + * + * @param totalFinalized + * true if the result of {@link #getTotalBlocks()} + * is final, false otherwise + */ + void setTotalFinalized(boolean totalFinalized) { + this.totalFinalized = totalFinalized; + } + +} -- 2.7.4