Package org.eclipse.ecf.protocol.bittorrent

Source Code of org.eclipse.ecf.protocol.bittorrent.Torrent

/*******************************************************************************
* 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.protocol.bittorrent;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.channels.SocketChannel;
import java.util.Properties;

import org.eclipse.ecf.protocol.bittorrent.internal.net.TorrentManager;

/**
* The <code>Torrent</code> class is used for hooking onto a
* {@link TorrentFile} so that pieces can be exchanged with peers.
*/
public class Torrent {

  /**
   * The {@link TorrentManager} that is managing all of the backend functions
   * of this torrent.
   */
  private final TorrentManager manager;

  /**
   * The 20-length SHA-1 hash of the torrent file's metainfo's
   * <code>info</code> dictionary.
   */
  private final String infoHash;

  /**
   * Creates a new <code>Torrent</code> to begin with exchanging pieces with
   * other pieces for the given torrent.
   *
   * @param torrent
   *            the torrent file to use
   * @param properties
   *            a <code>Properties</code> instance for storing information,
   *            this can be <code>null</code>
   * @throws IOException
   *             If an I/O error occurs whilst creating or hooking up with the
   *             files associated with the torrent
   */
  Torrent(TorrentFile torrent, Properties properties) throws IOException {
    manager = new TorrentManager(torrent, properties);
    infoHash = torrent.getInfoHash();
  }

  /**
   * Bridges the connection with the provided channel.
   *
   * @param channel
   *            the channel to connect to
   * @throws UnsupportedEncodingException
   *             If the <code>ISO-8859-1</code> encoding is not supported
   */
  void connectTo(SocketChannel channel) throws UnsupportedEncodingException {
    manager.connectTo(channel);
  }

  /**
   * Contacts the tracker to begin exchanging pieces with any peers that are
   * found.
   *
   * @throws IOException
   *             If an error occurs while querying the tracker or connecting
   *             to one of the provided peers
   */
  public void start() throws IOException {
    manager.start();
    TorrentServer.addTorrent(infoHash, this);
  }

  /**
   * Stops downloading, seeding, or the hash checking process for this
   * torrent. It is crucial that this method be called for termination as it
   * will perform clean-up on lingering threads that are performing background
   * operations.
   *
   * @throws IOException
   *             If an IOException occurred while informing the tracker that
   *             the client is stopping
   */
  public void stop() throws IOException {
    TorrentServer.remove(infoHash);
    manager.stop();
  }

  /**
   * Removes all previously saved status and configuration information
   * regarding the opened torrent. This will call {@link #stop()} prior to the
   * deletion of the files.
   */
  public void remove() {
    TorrentServer.remove(infoHash);
    manager.remove();
  }

  /**
   * Removes all information pertaining to the opened torrent in addition to
   * removing the target that has been set for downloading or seeding.
   *
   * @return <code>true</code> if the target file or directory has been
   *         deleted successfully, <code>false</code> otherwise
   */
  public boolean delete() {
    TorrentServer.remove(infoHash);
    return manager.delete();
  }

  /**
   * Performs a hash check on all pieces for this torrnet in a separate
   * thread. This may not necessarily run if the torrent is currently
   * performing other actions. The returned value will indicate whether the
   * hash check is being performed or not.
   *
   * @return <code>true</code> if the torrent will begin performing hash
   *         check on its pieces on a separate thread or is already running a
   *         hash check, </code>false</code> if the torrent is currently
   *         performing other operations and is unable to run a hash check
   */
  public boolean performHashCheck() {
    return manager.performHashCheck();
  }

  /**
   * Adds the specified listener to the collection of listeners for this
   * torrent if it is not already contained. The listener will be notified of
   * the changes of the current state of the torrent's activity. The event's
   * state will correspond to the value returned from {@link #getState()}.
   *
   * @param listener
   *            the listener to notify
   * @throws IllegalArgumentException
   *             If <code>listener</code> is <code>null</code>
   */
  public void addTorrentStateListener(ITorrentStateListener listener)
      throws IllegalArgumentException {
    if (listener == null) {
      throw new IllegalArgumentException("The listener cannot be null"); //$NON-NLS-1$
    }
    manager.addTorrentStateListener(listener);
  }

  /**
   * Adds the specified listener to the collection of listeners for this
   * torrent if it is not already contained. The listener will be notified
   * when another piece has been completed by verifying it against a hash sum.
   *
   * @param listener
   *            the listener to notify
   * @throws IllegalArgumentException
   *             If <code>listener</code> is <code>null</code>
   */
  public void addTorrentProgressListener(ITorrentProgressListener listener)
      throws IllegalArgumentException {
    if (listener == null) {
      throw new IllegalArgumentException("The listener cannot be null"); //$NON-NLS-1$
    }
    manager.addTorrentProgressListener(listener);
  }

  /**
   * Adds the specified listener to the collection of listeners for this
   * torrent if it is not already contained. The listener will be notified
   * when a piece has downloaded some amount of additional bytes.
   *
   * @param listener
   *            the listener to notify
   * @throws IllegalArgumentException
   *             If <code>listener</code> is <code>null</code>
   */
  public void addPieceProgressListener(IPieceProgressListener listener)
      throws IllegalArgumentException {
    if (listener == null) {
      throw new IllegalArgumentException("The listener cannot be null"); //$NON-NLS-1$
    }
    manager.addPieceProgressListener(listener);
  }

  /**
   * Adds the specified listener to the collection of listeners for this
   * torrent if it is not already contained. The listener will be notified
   * when a piece has successfully completed its hash check.
   *
   * @param listener
   *            the listener to notify
   * @throws IllegalArgumentException
   *             If <code>listener</code> is <code>null</code>
   */
  public void addHashCheckListener(IHashCheckListener listener) {
    if (listener == null) {
      throw new IllegalArgumentException("The listener cannot be null"); //$NON-NLS-1$
    }
    manager.addHashCheckListener(listener);
  }

  /**
   * Adds the specified listener to the collection of listeners for this
   * torrent if it is not already contained. The listener will be notified
   * when errors such as tracker failures or hash check failures occurs.
   *
   * @param listener
   *            the listener to notify
   * @throws IllegalArgumentException
   *             If <code>listener</code> is <code>null</code>
   */
  public void addTorrentErrorListener(ITorrentErrorListener listener)
      throws IllegalArgumentException {
    if (listener == null) {
      throw new IllegalArgumentException("The listener cannot be null"); //$NON-NLS-1$
    }
    manager.addTorrentErrorListener(listener);
  }

  /**
   * Removes the specified listener so that it will no longer be notified of
   * state updates.
   *
   * @param listener
   *            the listener to remove
   * @return <code>true</code> if one such listener was removed,
   *         <code>false</code> otherwise
   */
  public boolean removeTorrentStateListener(ITorrentStateListener listener) {
    return manager.removeTorrentStateListener(listener);
  }

  /**
   * Removes the specified listener so that it will no longer be notified when
   * pieces has been completed.
   *
   * @param listener
   *            the listener to remove
   * @return <code>true</code> if one such listener was removed,
   *         <code>false</code> otherwise
   */
  public boolean removeTorrentProgressListener(
      ITorrentProgressListener listener) {
    return manager.removeTorrentProgressListener(listener);
  }

  /**
   * Removes the specified listener so that it will no longer be notified of a
   * piece having downloaded some additional bytes.
   *
   * @param listener
   *            the listener to remove
   * @return <code>true</code> if one such listener was removed,
   *         <code>false</code> otherwise
   */
  public boolean removePieceProgressListener(IPieceProgressListener listener) {
    return manager.removePieceProgressListener(listener);
  }

  /**
   * Removes the specified listener so that it will no longer be notified of
   * pieces have completed the hash checking process.
   *
   * @param listener
   *            the listener to remove
   * @return <code>true</code> if one such listener was removed,
   *         <code>false</code> otherwise
   */
  public boolean removeHashCheckListener(IHashCheckListener listener) {
    return manager.removeHashCheckListener(listener);
  }

  /**
   * Removes the specified listener so that it will no longer be notified of
   * errors.
   *
   * @param listener
   *            the listener to remove
   * @return <code>true</code> if one such listener was removed,
   *         <code>false</code> otherwise
   */
  public boolean removeTorrentErrorListener(ITorrentErrorListener listener) {
    return manager.removeTorrentErrorListener(listener);
  }

  /**
   * Sets the maximum number of connections that this torrent should attempt
   * to connect to. The default value is set to 50 although 30 peers should
   * already be plenty. This value should not be heightened unless there is a
   * good reason to do so as it will likely cause network congestions.
   *
   * @param maxConnections
   *            the maximum number of connections that should be used
   * @throws IllegalArgumentException
   *             If <code>maxConnections</code> is negative
   */
  public void setMaxConnections(int maxConnections)
      throws IllegalArgumentException {
    if (maxConnections < 0) {
      throw new IllegalArgumentException("The maximum number of connections cannot be negative"); //$NON-NLS-1$
    }
    manager.setMaxConnections(maxConnections);
  }

  /**
   * Setup file download priority levels and whether a file should even be
   * downloaded at all.
   *
   * @param downloadChoices
   *            an integer array which stores a value greater than zero if the
   *            file should have a high priority, a value equal to zero if it
   *            should have a regular priority, or less than zero if it should
   *            not be downloaded at all, the values should correspond to the
   *            files returned from {@link TorrentFile}'s
   *            {@link TorrentFile#getFilenames()} method
   * @throws IllegalArgumentException
   *             If <code>downloadChoices</code> is <code>null</code> or
   *             if the length of the array is not equal to the number of
   *             files for this torrent
   */
  public void setFilesToDownload(int[] downloadChoices) {
    if (downloadChoices == null) {
      throw new IllegalArgumentException("The array cannot be null"); //$NON-NLS-1$
    }
    manager.setFilesToDownload(downloadChoices);
  }

  /**
   * Retrieves the amount that has been downloaded thus far since the original
   * call to {@link #start()}.
   *
   * @return the amount of bytes that has been downloaded from peers
   */
  public long getDownloaded() {
    return manager.getDownloaded();
  }

  /**
   * Returns the number of bytes that has been uploaded to peers thus far
   * since calling {@link #start()}.
   *
   * @return the amount of bytes that has been uploaded to peers
   */
  public long getUploaded() {
    return manager.getUploaded();
  }

  /**
   * Retreives the number of bytes that are required to complete the download.
   *
   * @return the number of bytes left to complete the download
   */
  public long getRemaining() {
    return manager.getRemaining();
  }

  /**
   * Gets the downloading speed as calculated over a twenty second rolling
   * average.
   *
   * @return the speed at which bytes are being downloaded from peers
   */
  public long getDownSpeed() {
    return manager.getDownSpeed();
  }

  /**
   * Retrieves the uploading speed per calculations over a twenty second
   * rolling average.
   *
   * @return the speed at which bytes are being uploaded to peers
   */
  public long getUpSpeed() {
    return manager.getUpSpeed();
  }

  /**
   * Sets the maximum number of bytes to download per second from peers. If
   * <code>maximum</code> is zero or negative, the speed capping limit will
   * be lifted.
   *
   * @param maximum
   *            the maximum number of bytes that should be downloaded from
   *            peers per second
   */
  public void setMaxDownloadSpeed(long maximum) {
    manager.setMaxDownloadSpeed(maximum);
  }

  /**
   * Sets the maximum number of bytes to upload per second to peers. If
   * <code>maximum</code> is zero or negative, the speed capping limit will
   * be lifted.
   *
   * @param maximum
   *            the maximum number of bytes that should be uploaded to peers
   *            per second
   */
  public void setMaxUploadSpeed(long maximum) {
    manager.setMaxUploadSpeed(maximum);
  }

  /**
   * Retrieves the time in seconds that are remaining for this download to
   * complete. If the returned value is <code>-1</code>, the time is
   * unknown. This will be returned when the downloading speed is at 0.
   *
   * @return the time remaining in seconds for the download to complete or
   *         <code>-1</code> if the value is not known
   */
  public long getTimeRemaining() {
    return manager.getTimeRemaining();
  }

  /**
   * Retrieves the amount of data that has been discarded thus far. This is
   * caused by pieces that has failed the integrity hash check.
   *
   * @return the amount of bytes that has been discarded
   */
  public long getDiscarded() {
    return manager.getDiscarded();
  }

  /**
   * Retrieves the number of peers that connections have been created for thus
   * far.
   *
   * @return the number of connected peers
   */
  public int getConnectedPeers() {
    return manager.getConnectedPeers();
  }

  /**
   * Returns the number of seeds that are currently assisting with the
   * distribution.
   *
   * @return the number of connected seeds, if the value is <code>-1</code>,
   *         the tracker does not support the distribution of this information
   * @see #getPeers()
   */
  public int getSeeds() {
    return manager.getSeeds();
  }

  /**
   * Returns the total number of peers that are attempting to download this
   * torrent.
   *
   * @return the total number of connected peers on the torrent, if the value
   *         is <code>-1</code>, the tracker does not support the
   *         distribution of this information
   * @see #getSeeds()
   */
  public int getPeers() {
    return manager.getPeers();
  }

  /**
   * Retrieves the torrent file that was used to create this torrent.
   *
   * @return the {@link TorrentFile} that initialized this
   */
  public TorrentFile getTorrentFile() {
    return manager.getTorrentFile();
  }

  /**
   * Retrieves the current state in which this torrent is currently in. This
   * could be any one of the states provided by the
   * {@link ITorrentStateListener} interface.
   *
   * @return the state that this torrent is currently in
   * @see ITorrentStateListener#STARTED
   * @see ITorrentStateListener#EXCHANGING
   * @see ITorrentStateListener#STOPPED
   * @see ITorrentStateListener#FINISHED
   * @see ITorrentStateListener#HASH_CHECKING
   */
  public int getState() {
    return manager.getState();
  }
}
TOP

Related Classes of org.eclipse.ecf.protocol.bittorrent.Torrent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.