From 16353715c279d8b535b7aabb287764e591788c92 Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Thu, 17 Apr 2008 00:34:07 +0000 Subject: [PATCH] add identifier to all requests start implementation of download git-svn-id: http://trooper/svn/projects/jFCPlib/branch/high-level-client@839 c3eda9e8-030b-0410-8277-bc7414b0a119 --- .../pterodactylus/fcp/highlevel/ConnectResult.java | 1 + .../fcp/highlevel/DirectDiskAccessResult.java | 6 +- .../fcp/highlevel/DownloadResult.java | 40 +++++ .../fcp/highlevel/HighLevelCallback.java | 4 +- .../fcp/highlevel/HighLevelCallbackListener.java | 2 +- .../fcp/highlevel/HighLevelClient.java | 100 +++++++++++- .../fcp/highlevel/HighLevelContinuousCallback.java | 159 ------------------ .../HighLevelContinuousCallbackListener.java | 41 ----- .../fcp/highlevel/HighLevelContinuousResult.java | 169 ------------------- .../fcp/highlevel/HighLevelProgress.java | 179 +++++++++++++++++++++ .../fcp/highlevel/HighLevelProgressCallback.java | 127 +++++++++++++++ .../HighLevelProgressCallbackListener.java | 43 +++++ .../fcp/highlevel/HighLevelResult.java | 22 +++ .../fcp/highlevel/KeyGenerationResult.java | 6 +- .../fcp/highlevel/PeerListResult.java | 10 ++ .../pterodactylus/fcp/highlevel/PeerResult.java | 10 ++ 16 files changed, 539 insertions(+), 380 deletions(-) create mode 100644 src/net/pterodactylus/fcp/highlevel/DownloadResult.java delete mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java delete mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java delete mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelProgress.java create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallback.java create mode 100644 src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallbackListener.java diff --git a/src/net/pterodactylus/fcp/highlevel/ConnectResult.java b/src/net/pterodactylus/fcp/highlevel/ConnectResult.java index d922292..1236038 100644 --- a/src/net/pterodactylus/fcp/highlevel/ConnectResult.java +++ b/src/net/pterodactylus/fcp/highlevel/ConnectResult.java @@ -34,6 +34,7 @@ public class ConnectResult extends HighLevelResult { * Package-private constructor. */ ConnectResult() { + super(null); } /** diff --git a/src/net/pterodactylus/fcp/highlevel/DirectDiskAccessResult.java b/src/net/pterodactylus/fcp/highlevel/DirectDiskAccessResult.java index fc841d2..84f33c3 100644 --- a/src/net/pterodactylus/fcp/highlevel/DirectDiskAccessResult.java +++ b/src/net/pterodactylus/fcp/highlevel/DirectDiskAccessResult.java @@ -35,8 +35,12 @@ public class DirectDiskAccessResult extends HighLevelResult { /** * Package-private constructor. + * + * @param identifier + * The identifier of the request */ - DirectDiskAccessResult() { + DirectDiskAccessResult(String identifier) { + super(identifier); } /** diff --git a/src/net/pterodactylus/fcp/highlevel/DownloadResult.java b/src/net/pterodactylus/fcp/highlevel/DownloadResult.java new file mode 100644 index 0000000..c6a237a --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/DownloadResult.java @@ -0,0 +1,40 @@ +/* + * jFCPlib-high-level-client - DownloadResult.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; + +/** + * The result of a download. + * + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class DownloadResult extends HighLevelProgress { + + /** + * Package-private constructor. + * + * @param identifier + * The identifier of the request + */ + public DownloadResult(String identifier) { + super(identifier); + } + +} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java index 27fc6bb..ac448a6 100644 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelCallback.java @@ -35,13 +35,13 @@ import java.util.List; public class HighLevelCallback { /** Object used for synchronization. */ - private final Object syncObject = new Object(); + protected final Object syncObject = new Object(); /** The list of callback listeners. */ private final List> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList>()); /** Whether the result is complete. */ - private boolean resultComplete = false; + protected boolean resultComplete = false; /** The result of the operation. */ private R result = null; diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelCallbackListener.java b/src/net/pterodactylus/fcp/highlevel/HighLevelCallbackListener.java index 36a2cc4..78d41b0 100644 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelCallbackListener.java +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelCallbackListener.java @@ -26,7 +26,7 @@ import java.util.EventListener; * {@link HighLevelCallback} received a result. * * @param - * The type of the high-level operation result + * The type of the high-level operation progress * @author David ‘Bombe’ Roden <bombe@freenetproject.org> * @version $Id$ */ diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelClient.java b/src/net/pterodactylus/fcp/highlevel/HighLevelClient.java index 089c205..0ec6da6 100644 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelClient.java +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelClient.java @@ -35,6 +35,7 @@ import java.util.logging.Logger; import net.pterodactylus.fcp.AddPeer; import net.pterodactylus.fcp.AllData; +import net.pterodactylus.fcp.ClientGet; import net.pterodactylus.fcp.ClientHello; import net.pterodactylus.fcp.CloseConnectionDuplicateClientName; import net.pterodactylus.fcp.ConfigData; @@ -68,6 +69,7 @@ import net.pterodactylus.fcp.ProtocolError; import net.pterodactylus.fcp.PutFailed; import net.pterodactylus.fcp.PutFetchable; import net.pterodactylus.fcp.PutSuccessful; +import net.pterodactylus.fcp.ReturnType; import net.pterodactylus.fcp.SSKKeypair; import net.pterodactylus.fcp.SimpleProgress; import net.pterodactylus.fcp.StartedCompression; @@ -125,6 +127,9 @@ public class HighLevelClient { /** Mapping from directories to DDA callbacks. */ private Map> directDiskAccessCallbacks = Collections.synchronizedMap(new HashMap>()); + /** Mapping from request identifiers to download callbacks. */ + private Map> downloadCallbacks = Collections.synchronizedMap(new HashMap>()); + /** * Creates a new high-level client that connects to a node on * localhost. @@ -227,7 +232,7 @@ public class HighLevelClient { public HighLevelCallback generateKey() throws IOException { String identifier = generateIdentifier("generateSSK"); GenerateSSK generateSSK = new GenerateSSK(identifier); - HighLevelCallback keyGenerationCallback = new HighLevelCallback(new KeyGenerationResult()); + HighLevelCallback keyGenerationCallback = new HighLevelCallback(new KeyGenerationResult(identifier)); keyGenerationCallbacks.put(identifier, keyGenerationCallback); fcpConnection.sendMessage(generateSSK); return keyGenerationCallback; @@ -243,7 +248,7 @@ public class HighLevelClient { public HighLevelCallback getPeers() throws IOException { String identifier = generateIdentifier("listPeers"); ListPeers listPeers = new ListPeers(identifier, true, true); - HighLevelCallback peerListCallback = new HighLevelCallback(new PeerListResult()); + HighLevelCallback peerListCallback = new HighLevelCallback(new PeerListResult(identifier)); peerListCallbacks.put(identifier, peerListCallback); fcpConnection.sendMessage(listPeers); return peerListCallback; @@ -261,7 +266,7 @@ public class HighLevelClient { public HighLevelCallback addPeer(String nodeRefFile) throws IOException { String identifier = generateIdentifier("addPeer"); AddPeer addPeer = new AddPeer(nodeRefFile); - HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult()); + HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult(identifier)); peerCallbacks.put(identifier, peerCallback); fcpConnection.sendMessage(addPeer); return peerCallback; @@ -279,7 +284,7 @@ public class HighLevelClient { public HighLevelCallback addPeer(URL nodeRefURL) throws IOException { String identifier = generateIdentifier("addPeer"); AddPeer addPeer = new AddPeer(nodeRefURL); - HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult()); + HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult(identifier)); peerCallbacks.put(identifier, peerCallback); fcpConnection.sendMessage(addPeer); return peerCallback; @@ -297,7 +302,7 @@ public class HighLevelClient { public HighLevelCallback addPeer(NodeRef nodeRef) throws IOException { String identifier = generateIdentifier("addPeer"); AddPeer addPeer = new AddPeer(nodeRef); - HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult()); + HighLevelCallback peerCallback = new HighLevelCallback(new PeerResult(identifier)); peerCallbacks.put(identifier, peerCallback); fcpConnection.sendMessage(addPeer); return peerCallback; @@ -319,12 +324,40 @@ public class HighLevelClient { */ public HighLevelCallback checkDirectDiskAccess(String directory, boolean wantRead, boolean wantWrite) throws IOException { TestDDARequest testDDARequest = new TestDDARequest(directory, wantRead, wantWrite); - HighLevelCallback directDiskAccessCallback = new HighLevelCallback(new DirectDiskAccessResult()); + HighLevelCallback directDiskAccessCallback = new HighLevelCallback(new DirectDiskAccessResult(directory)); directDiskAccessCallbacks.put(directory, directDiskAccessCallback); fcpConnection.sendMessage(testDDARequest); return directDiskAccessCallback; } + /** + * Starts a download. Files can either be download to disk or streamed from + * the node. When downloading to disk you have to perform a direct disk + * access check for the directory you want to put the downloaded file in! + * + * @see #checkDirectDiskAccess(String, boolean, boolean) + * @param uri + * The URI to get + * @param filename + * The filename to save the data to, or null to + * retrieve the data as InputStream from the + * {@link DownloadResult} + * @param global + * Whether to put the download on the global queue + * @return A download result + * @throws IOException + * if an I/O error occurs communicating with the node + */ + public HighLevelProgressCallback download(String uri, String filename, boolean global) throws IOException { + String identifier = generateIdentifier("download"); + ClientGet clientGet = new ClientGet(uri, identifier, (filename == null) ? ReturnType.direct : ReturnType.disk); + clientGet.setGlobal(global); + HighLevelProgressCallback downloadCallback = new HighLevelProgressCallback(new DownloadResult(identifier)); + downloadCallbacks.put(identifier, downloadCallback); + fcpConnection.sendMessage(clientGet); + return downloadCallback; + } + // // PRIVATE METHODS // @@ -403,6 +436,12 @@ public class HighLevelClient { directDiskAccessEntry.getValue().setDone(); } directDiskAccessCallbacks.clear(); + /* download callbacks. */ + for (Entry> downloadEntry: downloadCallbacks.entrySet()) { + downloadEntry.getValue().getIntermediaryResult().setFailed(true); + downloadEntry.getValue().setDone(); + } + downloadCallbacks.clear(); } else { HighLevelCallback keyGenerationCallback = keyGenerationCallbacks.remove(identifier); if (keyGenerationCallback != null) { @@ -428,6 +467,12 @@ public class HighLevelClient { directDiskAccessCallback.setDone(); return; } + HighLevelProgressCallback downloadCallback = downloadCallbacks.remove(identifier); + if (downloadCallback != null) { + downloadCallback.getIntermediaryResult().setFailed(true); + downloadCallback.setDone(); + return; + } } } @@ -582,7 +627,20 @@ public class HighLevelClient { * @see net.pterodactylus.fcp.FcpListener#receivedGetFailed(net.pterodactylus.fcp.FcpConnection, * net.pterodactylus.fcp.GetFailed) */ + @SuppressWarnings("synthetic-access") public void receivedGetFailed(FcpConnection fcpConnection, GetFailed getFailed) { + if (fcpConnection != HighLevelClient.this.fcpConnection) { + return; + } + String identifier = getFailed.getIdentifier(); + HighLevelProgressCallback downloadCallback = downloadCallbacks.remove(identifier); + if (downloadCallback != null) { + downloadCallback.getIntermediaryResult().setFailed(true); + downloadCallback.setDone(); + return; + } + /* unknown identifier? */ + logger.warning("unknown identifier for GetFailed: " + identifier); } /** @@ -644,7 +702,9 @@ public class HighLevelClient { if (peerResult != null) { peerResult.getIntermediaryResult().setPeer(peer); peerResult.setDone(); + return; } + logger.warning("got Peer message with unknown identifier: " + identifier); } /** @@ -665,7 +725,16 @@ public class HighLevelClient { * @see net.pterodactylus.fcp.FcpListener#receivedPersistentGet(net.pterodactylus.fcp.FcpConnection, * net.pterodactylus.fcp.PersistentGet) */ + @SuppressWarnings("synthetic-access") public void receivedPersistentGet(FcpConnection fcpConnection, PersistentGet persistentGet) { + if (fcpConnection != HighLevelClient.this.fcpConnection) { + return; + } + String identifier = persistentGet.getIdentifier(); + if (downloadCallbacks.containsKey(identifier)) { + /* ignore, because a download does not care about this. */ + return; + } } /** @@ -763,7 +832,26 @@ public class HighLevelClient { * @see net.pterodactylus.fcp.FcpListener#receivedSimpleProgress(net.pterodactylus.fcp.FcpConnection, * net.pterodactylus.fcp.SimpleProgress) */ + @SuppressWarnings("synthetic-access") public void receivedSimpleProgress(FcpConnection fcpConnection, SimpleProgress simpleProgress) { + if (fcpConnection != HighLevelClient.this.fcpConnection) { + return; + } + String identifier = simpleProgress.getIdentifier(); + HighLevelProgressCallback downloadCallback = downloadCallbacks.get(identifier); + if (downloadCallback != null) { + DownloadResult downloadResult = downloadCallback.getIntermediaryResult(); + downloadResult.setTotalBlocks(simpleProgress.getTotal()); + downloadResult.setRequiredBlocks(simpleProgress.getRequired()); + downloadResult.setSuccessfulBlocks(simpleProgress.getSucceeded()); + downloadResult.setFailedBlocks(simpleProgress.getFailed()); + downloadResult.setFatallyFailedBlocks(simpleProgress.getFatallyFailed()); + downloadResult.setTotalFinalized(simpleProgress.isFinalizedTotal()); + downloadCallback.progressUpdated(); + return; + } + /* unknown identifier? */ + logger.warning("unknown identifier for SimpleProgress: " + identifier); } /** diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java deleted file mode 100644 index 4f82b70..0000000 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallback.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 deleted file mode 100644 index 09636bc..0000000 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousCallbackListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 deleted file mode 100644 index 397b4a9..0000000 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelContinuousResult.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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; - } - -} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelProgress.java b/src/net/pterodactylus/fcp/highlevel/HighLevelProgress.java new file mode 100644 index 0000000..ec648f8 --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelProgress.java @@ -0,0 +1,179 @@ +/* + * 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 HighLevelProgress 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; + + /** + * Package-private constructor. + * + * @param identifier + * The identifier of the request + */ + public HighLevelProgress(String identifier) { + super(identifier); + } + + /** + * 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; + } + +} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallback.java b/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallback.java new file mode 100644 index 0000000..a292df8 --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallback.java @@ -0,0 +1,127 @@ +/* + * 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 high-level progress + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id$ + */ +public class HighLevelProgressCallback

extends HighLevelCallback

{ + + /** Callback listeners. */ + private final List> highLevelContinuousCallbackListeners = new ArrayList>(); + + /** + * Creates a new continuous callback with the given result. + * + * @see HighLevelCallback#HighLevelCallback(HighLevelResult) + * @param progress + * The result of the operation + */ + HighLevelProgressCallback(P progress) { + super(progress); + } + + // + // EVENT MANAGEMENT + // + + /** + * Adds a callback listener to this callback. + * + * @param highLevelContinuousCallbackListener + * The callback listener to add + */ + public void addHighLevelContinuousCallbackListener(HighLevelProgressCallbackListener

highLevelContinuousCallbackListener) { + highLevelContinuousCallbackListeners.add(highLevelContinuousCallbackListener); + fireGotProgress(); + } + + /** + * Removes a callback listener from this callback. + * + * @param highLevelContinuousCallbackListener + * The callback listener to remove + */ + public void removeHighLevelContinuousCallbackListener(HighLevelProgressCallbackListener

highLevelContinuousCallbackListener) { + highLevelContinuousCallbackListeners.remove(highLevelContinuousCallbackListener); + } + + /** + * Notifies all listeners that progress results have been received. + */ + private void fireGotProgress() { + for (HighLevelProgressCallbackListener

highLevelContinuousCallbackListener: highLevelContinuousCallbackListeners) { + highLevelContinuousCallbackListener.gotProgress(this); + } + } + + // + // ACCESSORS + // + + /** + * Waits for the next progress on this callback. Completion of the result + * also counts as progress. + * + * @throws InterruptedException + * if {@link Object#wait()} is interrupted + */ + public void waitForProgress() throws InterruptedException { + synchronized (syncObject) { + syncObject.wait(); + } + } + + /** + * Waits for the given amount of time (in milliseconds) for the next + * progress on this callback. Completion of the result also counts as + * progress. + * + * @param waitTime + * The maximum time to wait for progress + * @throws InterruptedException + * if {@link Object#wait()} is interrupted + */ + public void waitForProgress(long waitTime) throws InterruptedException { + synchronized (syncObject) { + syncObject.wait(waitTime); + } + } + + /** + * Notifies all listeners that the progress was updated. + */ + void progressUpdated() { + synchronized (syncObject) { + syncObject.notify(); + } + fireGotProgress(); + } + +} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallbackListener.java b/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallbackListener.java new file mode 100644 index 0000000..e0683fb --- /dev/null +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelProgressCallbackListener.java @@ -0,0 +1,43 @@ +/* + * 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 high-level progress + * @author David ‘Bombe’ Roden <bombe@freenetproject.org> + * @version $Id: HighLevelContinuousCallbackListener.java 29 2008-04-15 + * 23:15:49Z bombe $ + */ +public interface HighLevelProgressCallbackListener

extends HighLevelCallbackListener

{ + + /** + * Notifies a listener that a progress message has been received. + * + * @param highLevelContinuousCallback + * The callback that made the progress + */ + public void gotProgress(HighLevelProgressCallback

highLevelContinuousCallback); + +} diff --git a/src/net/pterodactylus/fcp/highlevel/HighLevelResult.java b/src/net/pterodactylus/fcp/highlevel/HighLevelResult.java index 3be5b2c..5975394 100644 --- a/src/net/pterodactylus/fcp/highlevel/HighLevelResult.java +++ b/src/net/pterodactylus/fcp/highlevel/HighLevelResult.java @@ -27,10 +27,32 @@ package net.pterodactylus.fcp.highlevel; */ public abstract class HighLevelResult { + /** The identifier of the request. */ + private final String identifier; + /** Whether the operation failed. */ private boolean failed; /** + * Package-private constructor. + * + * @param identifier + * The identifier of the request + */ + HighLevelResult(String identifier) { + this.identifier = identifier; + } + + /** + * Returns the identifier of the underlying request. + * + * @return The identifier of the request + */ + public String getIdentifier() { + return identifier; + } + + /** * Returns whether the operation failed. * * @return true if the operation failed, false diff --git a/src/net/pterodactylus/fcp/highlevel/KeyGenerationResult.java b/src/net/pterodactylus/fcp/highlevel/KeyGenerationResult.java index eeaa4a9..5d66351 100644 --- a/src/net/pterodactylus/fcp/highlevel/KeyGenerationResult.java +++ b/src/net/pterodactylus/fcp/highlevel/KeyGenerationResult.java @@ -35,8 +35,12 @@ public class KeyGenerationResult extends HighLevelResult { /** * Package-private constructor. + * + * @param identifier + * The identifier of the request */ - KeyGenerationResult() { + KeyGenerationResult(String identifier) { + super(identifier); } /** diff --git a/src/net/pterodactylus/fcp/highlevel/PeerListResult.java b/src/net/pterodactylus/fcp/highlevel/PeerListResult.java index 1d6e91f..456e01e 100644 --- a/src/net/pterodactylus/fcp/highlevel/PeerListResult.java +++ b/src/net/pterodactylus/fcp/highlevel/PeerListResult.java @@ -37,6 +37,16 @@ public class PeerListResult extends HighLevelResult implements Iterable { private final List peers = new ArrayList(); /** + * Package-private constructor. + * + * @param identifier + * The identifier of the request + */ + PeerListResult(String identifier) { + super(identifier); + } + + /** * Adds a peer to the list. * * @param peer diff --git a/src/net/pterodactylus/fcp/highlevel/PeerResult.java b/src/net/pterodactylus/fcp/highlevel/PeerResult.java index 47e78b5..a332761 100644 --- a/src/net/pterodactylus/fcp/highlevel/PeerResult.java +++ b/src/net/pterodactylus/fcp/highlevel/PeerResult.java @@ -36,6 +36,16 @@ public class PeerResult extends HighLevelResult { private Peer peer; /** + * Package-private constructor. + * + * @param identifier + * The identifier of the request + */ + PeerResult(String identifier) { + super(identifier); + } + + /** * Returns the peer. * * @return The peer -- 2.7.4