| /******************************************************************************* |
| * Copyright (c) 2006, 2008 Remy Suen, Composent Inc., and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Remy Suen <remy.suen@gmail.com> - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.ecf.internal.provider.bittorrent; |
| |
| import java.io.IOException; |
| import java.util.Date; |
| |
| import org.eclipse.ecf.core.identity.ID; |
| import org.eclipse.ecf.filetransfer.IFileRangeSpecification; |
| import org.eclipse.ecf.filetransfer.IFileTransferListener; |
| import org.eclipse.ecf.filetransfer.IFileTransferPausable; |
| import org.eclipse.ecf.filetransfer.IFileTransferRateControl; |
| import org.eclipse.ecf.filetransfer.IIncomingFileTransfer; |
| import org.eclipse.ecf.filetransfer.IOutgoingFileTransfer; |
| import org.eclipse.ecf.filetransfer.UserCancelledException; |
| import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveDataEvent; |
| import org.eclipse.ecf.filetransfer.events.IIncomingFileTransferReceiveDoneEvent; |
| import org.eclipse.ecf.protocol.bittorrent.IPieceProgressListener; |
| import org.eclipse.ecf.protocol.bittorrent.ITorrentStateListener; |
| import org.eclipse.ecf.protocol.bittorrent.Torrent; |
| |
| final class TorrentFileTransfer implements IFileTransferPausable, IFileTransferRateControl, IIncomingFileTransfer, IOutgoingFileTransfer { |
| |
| private final ID id; |
| |
| private final IFileTransferListener listener; |
| |
| private final Torrent torrent; |
| |
| private final IPieceProgressListener pieceListener; |
| |
| private final ITorrentStateListener stateListener; |
| |
| private final double total; |
| |
| private Exception exception; |
| |
| private boolean paused = false; |
| |
| TorrentFileTransfer(ID id, IFileTransferListener listener, Torrent torrent) { |
| this.id = id; |
| this.listener = listener; |
| this.torrent = torrent; |
| total = torrent.getTorrentFile().getTotalLength(); |
| |
| pieceListener = new IPieceProgressListener() { |
| public void blockDownloaded(int piece, int index, int blockLength) { |
| TorrentFileTransfer.this.listener.handleTransferEvent(new IIncomingFileTransferReceiveDataEvent() { |
| |
| public IIncomingFileTransfer getSource() { |
| return TorrentFileTransfer.this; |
| } |
| |
| }); |
| } |
| }; |
| |
| stateListener = new ITorrentStateListener() { |
| public void stateChanged(int state) { |
| if (state == ITorrentStateListener.FINISHED) { |
| notifyCompletion(null); |
| } |
| } |
| }; |
| |
| torrent.addPieceProgressListener(pieceListener); |
| torrent.addTorrentStateListener(stateListener); |
| |
| try { |
| torrent.start(); |
| } catch (final IOException e) { |
| notifyCompletion(e); |
| } |
| } |
| |
| private void notifyCompletion(Exception exception) { |
| this.exception = exception; |
| torrent.removePieceProgressListener(pieceListener); |
| torrent.removeTorrentStateListener(stateListener); |
| |
| listener.handleTransferEvent(new IIncomingFileTransferReceiveDoneEvent() { |
| |
| public Exception getException() { |
| return TorrentFileTransfer.this.exception; |
| } |
| |
| public IIncomingFileTransfer getSource() { |
| return TorrentFileTransfer.this; |
| } |
| |
| }); |
| } |
| |
| public void cancel() { |
| try { |
| torrent.stop(); |
| notifyCompletion(new UserCancelledException()); |
| } catch (final IOException e) { |
| notifyCompletion(e); |
| } |
| } |
| |
| public long getBytesSent() { |
| return torrent.getUploaded(); |
| } |
| |
| public Exception getException() { |
| return exception; |
| } |
| |
| public double getPercentComplete() { |
| return (total - torrent.getRemaining()) / total; |
| } |
| |
| public Object getAdapter(Class adapter) { |
| return adapter.isInstance(this) ? this : null; |
| } |
| |
| public ID getID() { |
| return id; |
| } |
| |
| public long getBytesReceived() { |
| return torrent.getDownloaded(); |
| } |
| |
| public boolean isDone() { |
| return exception != null || getPercentComplete() == 1; |
| } |
| |
| public boolean pause() { |
| if (paused || isDone()) { |
| return false; |
| } |
| |
| try { |
| torrent.stop(); |
| paused = true; |
| return true; |
| } catch (final IOException e) { |
| notifyCompletion(e); |
| return false; |
| } |
| } |
| |
| public boolean resume() { |
| if (!paused || isDone()) { |
| return false; |
| } |
| |
| try { |
| torrent.start(); |
| paused = false; |
| return true; |
| } catch (final IOException e) { |
| notifyCompletion(e); |
| return false; |
| } |
| } |
| |
| public void setMaxDownloadSpeed(long maxDownloadSpeed) { |
| torrent.setMaxDownloadSpeed(maxDownloadSpeed); |
| } |
| |
| public void setMaxUploadSpeed(long maxUploadSpeed) { |
| torrent.setMaxUploadSpeed(maxUploadSpeed); |
| } |
| |
| public boolean isPaused() { |
| return paused; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getListener() |
| */ |
| public IFileTransferListener getListener() { |
| return listener; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getFileRangeSpecification() |
| */ |
| public IFileRangeSpecification getFileRangeSpecification() { |
| return null; |
| } |
| |
| public long getFileLength() { |
| return torrent.getTorrentFile().getTotalLength(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getRemoteFileName() |
| */ |
| public String getRemoteFileName() { |
| if (torrent == null) |
| return null; |
| if (!torrent.getTorrentFile().isMultiFile()) { |
| return torrent.getTorrentFile().getFilenames()[0]; |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ecf.filetransfer.IIncomingFileTransfer#getRemoteLastModified() |
| */ |
| public Date getRemoteLastModified() { |
| // Not supported |
| return null; |
| } |
| |
| } |