* Package-private constructor.
*/
ConnectResult() {
+ super(null);
}
/**
/**
* Package-private constructor.
+ *
+ * @param identifier
+ * The identifier of the request
*/
- DirectDiskAccessResult() {
+ DirectDiskAccessResult(String identifier) {
+ super(identifier);
}
/**
--- /dev/null
+/*
+ * 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);
+ }
+
+}
public class HighLevelCallback<R extends HighLevelResult> {
/** Object used for synchronization. */
- private final Object syncObject = new Object();
+ protected final Object syncObject = new Object();
/** The list of callback listeners. */
private final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
/** Whether the result is complete. */
- private boolean resultComplete = false;
+ protected boolean resultComplete = false;
/** The result of the operation. */
private R result = null;
* {@link HighLevelCallback} received a result.
*
* @param <R>
- * 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$
*/
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;
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;
/** Mapping from directories to DDA callbacks. */
private Map<String, HighLevelCallback<DirectDiskAccessResult>> directDiskAccessCallbacks = Collections.synchronizedMap(new HashMap<String, HighLevelCallback<DirectDiskAccessResult>>());
+ /** Mapping from request identifiers to download callbacks. */
+ private Map<String, HighLevelProgressCallback<DownloadResult>> downloadCallbacks = Collections.synchronizedMap(new HashMap<String, HighLevelProgressCallback<DownloadResult>>());
+
/**
* Creates a new high-level client that connects to a node on
* <code>localhost</code>.
public HighLevelCallback<KeyGenerationResult> generateKey() throws IOException {
String identifier = generateIdentifier("generateSSK");
GenerateSSK generateSSK = new GenerateSSK(identifier);
- HighLevelCallback<KeyGenerationResult> keyGenerationCallback = new HighLevelCallback<KeyGenerationResult>(new KeyGenerationResult());
+ HighLevelCallback<KeyGenerationResult> keyGenerationCallback = new HighLevelCallback<KeyGenerationResult>(new KeyGenerationResult(identifier));
keyGenerationCallbacks.put(identifier, keyGenerationCallback);
fcpConnection.sendMessage(generateSSK);
return keyGenerationCallback;
public HighLevelCallback<PeerListResult> getPeers() throws IOException {
String identifier = generateIdentifier("listPeers");
ListPeers listPeers = new ListPeers(identifier, true, true);
- HighLevelCallback<PeerListResult> peerListCallback = new HighLevelCallback<PeerListResult>(new PeerListResult());
+ HighLevelCallback<PeerListResult> peerListCallback = new HighLevelCallback<PeerListResult>(new PeerListResult(identifier));
peerListCallbacks.put(identifier, peerListCallback);
fcpConnection.sendMessage(listPeers);
return peerListCallback;
public HighLevelCallback<PeerResult> addPeer(String nodeRefFile) throws IOException {
String identifier = generateIdentifier("addPeer");
AddPeer addPeer = new AddPeer(nodeRefFile);
- HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult());
+ HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult(identifier));
peerCallbacks.put(identifier, peerCallback);
fcpConnection.sendMessage(addPeer);
return peerCallback;
public HighLevelCallback<PeerResult> addPeer(URL nodeRefURL) throws IOException {
String identifier = generateIdentifier("addPeer");
AddPeer addPeer = new AddPeer(nodeRefURL);
- HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult());
+ HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult(identifier));
peerCallbacks.put(identifier, peerCallback);
fcpConnection.sendMessage(addPeer);
return peerCallback;
public HighLevelCallback<PeerResult> addPeer(NodeRef nodeRef) throws IOException {
String identifier = generateIdentifier("addPeer");
AddPeer addPeer = new AddPeer(nodeRef);
- HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult());
+ HighLevelCallback<PeerResult> peerCallback = new HighLevelCallback<PeerResult>(new PeerResult(identifier));
peerCallbacks.put(identifier, peerCallback);
fcpConnection.sendMessage(addPeer);
return peerCallback;
*/
public HighLevelCallback<DirectDiskAccessResult> checkDirectDiskAccess(String directory, boolean wantRead, boolean wantWrite) throws IOException {
TestDDARequest testDDARequest = new TestDDARequest(directory, wantRead, wantWrite);
- HighLevelCallback<DirectDiskAccessResult> directDiskAccessCallback = new HighLevelCallback<DirectDiskAccessResult>(new DirectDiskAccessResult());
+ HighLevelCallback<DirectDiskAccessResult> directDiskAccessCallback = new HighLevelCallback<DirectDiskAccessResult>(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 <code>null</code> 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<DownloadResult> 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<DownloadResult> downloadCallback = new HighLevelProgressCallback<DownloadResult>(new DownloadResult(identifier));
+ downloadCallbacks.put(identifier, downloadCallback);
+ fcpConnection.sendMessage(clientGet);
+ return downloadCallback;
+ }
+
//
// PRIVATE METHODS
//
directDiskAccessEntry.getValue().setDone();
}
directDiskAccessCallbacks.clear();
+ /* download callbacks. */
+ for (Entry<String, HighLevelProgressCallback<DownloadResult>> downloadEntry: downloadCallbacks.entrySet()) {
+ downloadEntry.getValue().getIntermediaryResult().setFailed(true);
+ downloadEntry.getValue().setDone();
+ }
+ downloadCallbacks.clear();
} else {
HighLevelCallback<KeyGenerationResult> keyGenerationCallback = keyGenerationCallbacks.remove(identifier);
if (keyGenerationCallback != null) {
directDiskAccessCallback.setDone();
return;
}
+ HighLevelProgressCallback<DownloadResult> downloadCallback = downloadCallbacks.remove(identifier);
+ if (downloadCallback != null) {
+ downloadCallback.getIntermediaryResult().setFailed(true);
+ downloadCallback.setDone();
+ return;
+ }
}
}
* @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<DownloadResult> downloadCallback = downloadCallbacks.remove(identifier);
+ if (downloadCallback != null) {
+ downloadCallback.getIntermediaryResult().setFailed(true);
+ downloadCallback.setDone();
+ return;
+ }
+ /* unknown identifier? */
+ logger.warning("unknown identifier for GetFailed: " + identifier);
}
/**
if (peerResult != null) {
peerResult.getIntermediaryResult().setPeer(peer);
peerResult.setDone();
+ return;
}
+ logger.warning("got Peer message with unknown identifier: " + identifier);
}
/**
* @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;
+ }
}
/**
* @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<DownloadResult> 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);
}
/**
+++ /dev/null
-/*
- * 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 <bombe@freenetproject.org>
- * @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();
- }
-
-}
+++ /dev/null
-/*
- * 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 <bombe@freenetproject.org>
- * @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);
-
-}
+++ /dev/null
-/*
- * 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 <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;
- }
-
-}
--- /dev/null
+/*
+ * 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 <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;
+ }
+
+}
--- /dev/null
+/*
+ * 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
+ * <P>
+ * The type of the high-level progress
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ * @version $Id$
+ */
+public class HighLevelProgressCallback<P extends HighLevelProgress> extends HighLevelCallback<P> {
+
+ /** Callback listeners. */
+ private final List<HighLevelProgressCallbackListener<P>> highLevelContinuousCallbackListeners = new ArrayList<HighLevelProgressCallbackListener<P>>();
+
+ /**
+ * 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<P> highLevelContinuousCallbackListener) {
+ highLevelContinuousCallbackListeners.add(highLevelContinuousCallbackListener);
+ fireGotProgress();
+ }
+
+ /**
+ * Removes a callback listener from this callback.
+ *
+ * @param highLevelContinuousCallbackListener
+ * The callback listener to remove
+ */
+ public void removeHighLevelContinuousCallbackListener(HighLevelProgressCallbackListener<P> highLevelContinuousCallbackListener) {
+ highLevelContinuousCallbackListeners.remove(highLevelContinuousCallbackListener);
+ }
+
+ /**
+ * Notifies all listeners that progress results have been received.
+ */
+ private void fireGotProgress() {
+ for (HighLevelProgressCallbackListener<P> 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();
+ }
+
+}
--- /dev/null
+/*
+ * 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
+ * <P>
+ * 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<P extends HighLevelProgress> extends HighLevelCallbackListener<P> {
+
+ /**
+ * Notifies a listener that a progress message has been received.
+ *
+ * @param highLevelContinuousCallback
+ * The callback that made the progress
+ */
+ public void gotProgress(HighLevelProgressCallback<P> highLevelContinuousCallback);
+
+}
*/
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 <code>true</code> if the operation failed, <code>false</code>
/**
* Package-private constructor.
+ *
+ * @param identifier
+ * The identifier of the request
*/
- KeyGenerationResult() {
+ KeyGenerationResult(String identifier) {
+ super(identifier);
}
/**
private final List<Peer> peers = new ArrayList<Peer>();
/**
+ * Package-private constructor.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ PeerListResult(String identifier) {
+ super(identifier);
+ }
+
+ /**
* Adds a peer to the list.
*
* @param peer
private Peer peer;
/**
+ * Package-private constructor.
+ *
+ * @param identifier
+ * The identifier of the request
+ */
+ PeerResult(String identifier) {
+ super(identifier);
+ }
+
+ /**
* Returns the peer.
*
* @return The peer