/*
* File : DownloadImpl.java
* Created : 06-Jan-2004
* By : parg
*
* Azureus - a Java Bittorrent client
*
* 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.
*
* 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 ( see the LICENSE file ).
*
* 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 org.gudy.azureus2.pluginsimpl.local.download;
/**
* @author parg
*
*/
import java.io.File;
import java.util.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.core3.category.*;
import org.gudy.azureus2.core3.global.*;
import org.gudy.azureus2.core3.download.*;
import org.gudy.azureus2.core3.peer.*;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.tracker.client.*;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.torrent.TorrentAttribute;
import org.gudy.azureus2.plugins.peers.*;
import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerFileInfoImpl;
import org.gudy.azureus2.pluginsimpl.local.peers.*;
import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;
import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentManagerImpl;
import org.gudy.azureus2.plugins.disk.DiskManager;
import org.gudy.azureus2.plugins.disk.DiskManagerFileInfo;
import org.gudy.azureus2.plugins.download.Download;
import org.gudy.azureus2.plugins.download.DownloadActivationEvent;
import org.gudy.azureus2.plugins.download.DownloadActivationListener;
import org.gudy.azureus2.plugins.download.DownloadAttributeListener;
import org.gudy.azureus2.plugins.download.DownloadListener;
import org.gudy.azureus2.plugins.download.DownloadPeerListener;
import org.gudy.azureus2.plugins.download.DownloadPropertyListener;
import org.gudy.azureus2.plugins.download.DownloadPropertyEvent;
import org.gudy.azureus2.plugins.download.DownloadTrackerListener;
import org.gudy.azureus2.plugins.download.DownloadAnnounceResult;
import org.gudy.azureus2.plugins.download.DownloadScrapeResult;
import org.gudy.azureus2.plugins.download.DownloadStats;
import org.gudy.azureus2.plugins.download.DownloadException;
import org.gudy.azureus2.plugins.download.DownloadRemovalVetoException;
import org.gudy.azureus2.plugins.download.DownloadWillBeRemovedListener;
import org.gudy.azureus2.plugins.download.session.SessionAuthenticator;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.LogRelation;
import com.aelitis.azureus.core.util.CopyOnWriteList;
public class
DownloadImpl
extends LogRelation
implements Download, DownloadManagerListener,
DownloadManagerTrackerListener, DownloadManagerPeerListener,
DownloadManagerStateListener, DownloadManagerActivationListener
{
private DownloadManager download_manager;
private DownloadStatsImpl download_stats;
private int latest_state = ST_STOPPED;
private boolean latest_forcedStart;
private DownloadAnnounceResultImpl last_announce_result = new DownloadAnnounceResultImpl(this,null);
private DownloadScrapeResultImpl last_scrape_result = new DownloadScrapeResultImpl( this, null );
private TorrentImpl torrent = null;
private List listeners = new ArrayList();
private AEMonitor listeners_mon = new AEMonitor( "Download:L");
private List property_listeners = new ArrayList();
private List tracker_listeners = new ArrayList();
private AEMonitor tracker_listeners_mon = new AEMonitor( "Download:TL");
private List removal_listeners = new ArrayList();
private AEMonitor removal_listeners_mon = new AEMonitor( "Download:RL");
private List peer_listeners = new ArrayList();
private AEMonitor peer_listeners_mon = new AEMonitor( "Download:PL");
private DownloadPropertyListener attribute_listener_bridge = null;
private AEMonitor attr_listener_mon = new AEMonitor("Download:ATTR");
private Map read_attribute_listeners = new HashMap();
private Map write_attribute_listeners = new HashMap();
private CopyOnWriteList activation_listeners = new CopyOnWriteList();
private DownloadActivationEvent activation_state;
protected
DownloadImpl(
DownloadManager _dm )
{
download_manager = _dm;
download_stats = new DownloadStatsImpl( download_manager );
activation_state =
new DownloadActivationEvent()
{
public Download
getDownload()
{
return( DownloadImpl.this );
}
public int
getActivationCount()
{
return( download_manager.getActivationCount());
}
};
download_manager.addListener( this );
latest_forcedStart = download_manager.isForceStart();
}
// Not available to plugins
public DownloadManager
getDownload()
{
return( download_manager );
}
public int
getState()
{
return( convertState( download_manager.getState()) );
}
public int
getSubState()
{
int state = getState();
if ( state == ST_STOPPING ){
int substate = download_manager.getSubState();
if ( substate == DownloadManager.STATE_QUEUED ){
return( ST_QUEUED );
}else if ( substate == DownloadManager.STATE_STOPPED ){
return( ST_STOPPED );
}else if ( substate == DownloadManager.STATE_ERROR ){
return( ST_ERROR );
}
}
return( state );
}
protected int
convertState(
int dm_state )
{
// dm states: waiting -> initialising -> initialized ->
// disk states: allocating -> checking -> ready ->
// dm states: downloading -> finishing -> seeding -> stopping -> stopped
// "initialize" call takes from waiting -> initialising -> waiting (no port) or initialized (ok)
// if initialized then disk manager runs through to ready
// "startdownload" takes ready -> dl etc.
// "stopIt" takes to stopped which is equiv to ready
int our_state;
switch( dm_state ){
case DownloadManager.STATE_WAITING:
{
our_state = ST_WAITING;
break;
}
case DownloadManager.STATE_INITIALIZING:
case DownloadManager.STATE_INITIALIZED:
case DownloadManager.STATE_ALLOCATING:
case DownloadManager.STATE_CHECKING:
{
our_state = ST_PREPARING;
break;
}
case DownloadManager.STATE_READY:
{
our_state = ST_READY;
break;
}
case DownloadManager.STATE_DOWNLOADING:
case DownloadManager.STATE_FINISHING: // finishing download - transit to seeding
{
our_state = ST_DOWNLOADING;
break;
}
case DownloadManager.STATE_SEEDING:
{
our_state = ST_SEEDING;
break;
}
case DownloadManager.STATE_STOPPING:
{
our_state = ST_STOPPING;
break;
}
case DownloadManager.STATE_STOPPED:
{
our_state = ST_STOPPED;
break;
}
case DownloadManager.STATE_QUEUED:
{
our_state = ST_QUEUED;
break;
}
case DownloadManager.STATE_ERROR:
{
our_state = ST_ERROR;
break;
}
default:
{
our_state = ST_ERROR;
}
}
return( our_state );
}
public String
getErrorStateDetails()
{
return( download_manager.getErrorDetails());
}
public boolean
getFlag(
long flag )
{
return( download_manager.getDownloadState().getFlag( flag ));
}
public void setFlag(long flag, boolean set) {
download_manager.getDownloadState().setFlag(flag, set);
}
public int
getIndex()
{
GlobalManager globalManager = download_manager.getGlobalManager();
return globalManager.getIndexOf(download_manager);
}
public Torrent
getTorrent()
{
if (this.torrent != null) {return this.torrent;}
TOTorrent torrent = download_manager.getTorrent();
if (torrent == null) {return null;}
this.torrent = new TorrentImpl(torrent);
return this.torrent;
}
public void
initialize()
throws DownloadException
{
int state = download_manager.getState();
if ( state == DownloadManager.STATE_WAITING ){
download_manager.initialize();
}else{
throw( new DownloadException( "Download::initialize: download not waiting (state=" + state + ")" ));
}
}
public void
start()
throws DownloadException
{
int state = download_manager.getState();
if ( state == DownloadManager.STATE_READY ){
download_manager.startDownload();
}else{
throw( new DownloadException( "Download::start: download not ready (state=" + state + ")" ));
}
}
public void
restart()
throws DownloadException
{
int state = download_manager.getState();
if ( state == DownloadManager.STATE_STOPPED ||
state == DownloadManager.STATE_QUEUED ){
download_manager.setStateWaiting();
}else{
throw( new DownloadException( "Download::restart: download already running (state=" + state + ")" ));
}
}
public void
stop()
throws DownloadException
{
if ( download_manager.getState() != DownloadManager.STATE_STOPPED){
download_manager.stopIt( DownloadManager.STATE_STOPPED, false, false );
}else{
throw( new DownloadException( "Download::stop: download already stopped" ));
}
}
public void
stopAndQueue()
throws DownloadException
{
if ( download_manager.getState() != DownloadManager.STATE_QUEUED){
download_manager.stopIt( DownloadManager.STATE_QUEUED, false, false );
}else{
throw( new DownloadException( "Download::stopAndQueue: download already queued" ));
}
}
public void
recheckData()
throws DownloadException
{
if ( !download_manager.canForceRecheck()){
throw( new DownloadException( "Download::recheckData: download must be stopped, queued or in error state" ));
}
download_manager.forceRecheck();
}
public boolean
isStartStopLocked()
{
return( download_manager.getState() == DownloadManager.STATE_STOPPED );
}
public boolean
isForceStart()
{
return download_manager.isForceStart();
}
public void
setForceStart(boolean forceStart)
{
download_manager.setForceStart(forceStart);
}
public boolean
isPaused()
{
return( download_manager.isPaused());
}
public void
pause()
{
download_manager.pause();
}
public void
resume()
{
download_manager.resume();
}
public int
getPosition()
{
return download_manager.getPosition();
}
public long
getCreationTime()
{
return( download_manager.getCreationTime());
}
public void
setPosition(int newPosition)
{
download_manager.setPosition(newPosition);
}
public void
moveUp()
{
download_manager.getGlobalManager().moveUp(download_manager);
}
public void
moveDown()
{
download_manager.getGlobalManager().moveDown(download_manager);
}
public void
moveTo(
int pos )
{
download_manager.getGlobalManager().moveTo( download_manager, pos );
}
public String
getName()
{
return download_manager.getDisplayName();
}
public String getTorrentFileName() {
return download_manager.getTorrentFileName();
}
public String getCategoryName() {
Category category = download_manager.getDownloadState().getCategory();
if (category == null)
category = CategoryManager.getCategory(Category.TYPE_UNCATEGORIZED);
if (category == null)
return null;
return category.getName();
}
public String
getAttribute(
TorrentAttribute attribute )
{
String name = convertAttribute( attribute );
if ( name != null ){
return( download_manager.getDownloadState().getAttribute( name ));
}
return( null );
}
public String[]
getListAttribute(
TorrentAttribute attribute )
{
String name = convertAttribute( attribute );
if ( name != null ){
return( download_manager.getDownloadState().getListAttribute( name ));
}
return( null );
}
public void
setListAttribute(
TorrentAttribute attribute,
String[] value)
{
String name = convertAttribute(attribute);
if (name != null) {
download_manager.getDownloadState().setListAttribute(name, value);
}
}
public void
setMapAttribute(
TorrentAttribute attribute,
Map value )
{
String name = convertAttribute( attribute );
if ( name != null ){
// gotta clone before updating in case user has read values and then just
// updated them - setter code optimises out sets of the same values...
download_manager.getDownloadState().setMapAttribute( name, BEncoder.cloneMap( value ));
}
}
public Map
getMapAttribute(
TorrentAttribute attribute )
{
String name = convertAttribute( attribute );
if ( name != null ){
return( download_manager.getDownloadState().getMapAttribute( name ));
}
return( null );
}
public void
setAttribute(
TorrentAttribute attribute,
String value )
{
String name = convertAttribute( attribute );
if ( name != null ){
download_manager.getDownloadState().setAttribute( name, value );
}
}
public boolean hasAttribute(TorrentAttribute attribute) {
String name = convertAttribute(attribute);
if (name == null) {return false;}
return download_manager.getDownloadState().hasAttribute(name);
}
public boolean getBooleanAttribute(TorrentAttribute attribute) {
String name = convertAttribute(attribute);
if (name == null) {return false;} // Default value
return download_manager.getDownloadState().getBooleanAttribute(name);
}
public void setBooleanAttribute(TorrentAttribute attribute, boolean value) {
String name = convertAttribute(attribute);
if (name != null) {
download_manager.getDownloadState().setBooleanAttribute(name, value);
}
}
public int getIntAttribute(TorrentAttribute attribute) {
String name = convertAttribute(attribute);
if (name == null) {return 0;} // Default value
return download_manager.getDownloadState().getIntAttribute(name);
}
public void setIntAttribute(TorrentAttribute attribute, int value) {
String name = convertAttribute(attribute);
if (name != null) {
download_manager.getDownloadState().setIntAttribute(name, value);
}
}
public long getLongAttribute(TorrentAttribute attribute) {
String name = convertAttribute(attribute);
if (name == null) {return 0L;} // Default value
return download_manager.getDownloadState().getLongAttribute(name);
}
public void setLongAttribute(TorrentAttribute attribute, long value) {
String name = convertAttribute(attribute);
if (name != null) {
download_manager.getDownloadState().setLongAttribute(name, value);
}
}
protected String
convertAttribute(
TorrentAttribute attribute )
{
if ( attribute.getName() == TorrentAttribute.TA_CATEGORY ){
return( DownloadManagerState.AT_CATEGORY );
}else if ( attribute.getName() == TorrentAttribute.TA_NETWORKS ){
return( DownloadManagerState.AT_NETWORKS );
}else if ( attribute.getName() == TorrentAttribute.TA_TRACKER_CLIENT_EXTENSIONS ){
return( DownloadManagerState.AT_TRACKER_CLIENT_EXTENSIONS );
}else if ( attribute.getName() == TorrentAttribute.TA_PEER_SOURCES ){
return( DownloadManagerState.AT_PEER_SOURCES );
}else if ( attribute.getName() == TorrentAttribute.TA_DISPLAY_NAME ){
return( DownloadManagerState.AT_DISPLAY_NAME );
}else if ( attribute.getName() == TorrentAttribute.TA_USER_COMMENT ){
return( DownloadManagerState.AT_USER_COMMENT );
}else if ( attribute.getName() == TorrentAttribute.TA_RELATIVE_SAVE_PATH ){
return( DownloadManagerState.AT_RELATIVE_SAVE_PATH );
}else if ( attribute.getName() == TorrentAttribute.TA_SHARE_PROPERTIES ){
// this is a share-level attribute only, not propagated to individual downloads
return( null );
}else if ( attribute.getName().startsWith( "Plugin." )){
return( attribute.getName());
}else{
Debug.out( "Can't convert attribute '" + attribute.getName() + "'" );
return( null );
}
}
protected TorrentAttribute
convertAttribute(
String name )
{
if ( name.equals( DownloadManagerState.AT_CATEGORY )){
return( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_CATEGORY ));
}else if ( name.equals( DownloadManagerState.AT_NETWORKS )){
return( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_NETWORKS ));
}else if ( name.equals( DownloadManagerState.AT_PEER_SOURCES )){
return( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_PEER_SOURCES ));
}else if ( name.equals( DownloadManagerState.AT_TRACKER_CLIENT_EXTENSIONS )){
return( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_TRACKER_CLIENT_EXTENSIONS ));
}else if ( name.equals ( DownloadManagerState.AT_DISPLAY_NAME)){
return ( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_DISPLAY_NAME ));
}else if ( name.equals ( DownloadManagerState.AT_USER_COMMENT)){
return ( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_USER_COMMENT ));
}else if ( name.equals ( DownloadManagerState.AT_RELATIVE_SAVE_PATH)){
return ( TorrentManagerImpl.getSingleton().getAttribute( TorrentAttribute.TA_RELATIVE_SAVE_PATH ));
}else if ( name.startsWith( "Plugin." )){
return( TorrentManagerImpl.getSingleton().getAttribute( name ));
}else{
return( null );
}
}
public void setCategory(String sName) {
Category category = CategoryManager.getCategory(sName);
if (category == null)
category = CategoryManager.createCategory(sName);
download_manager.getDownloadState().setCategory(category);
}
public boolean isPersistent() {
return download_manager.isPersistent();
}
public void
remove()
throws DownloadException, DownloadRemovalVetoException
{
remove( false, false );
}
public void
remove(
boolean delete_torrent,
boolean delete_data )
throws DownloadException, DownloadRemovalVetoException
{
int dl_state = download_manager.getState();
if ( dl_state == DownloadManager.STATE_STOPPED ||
dl_state == DownloadManager.STATE_ERROR ||
dl_state == DownloadManager.STATE_QUEUED ){
GlobalManager globalManager = download_manager.getGlobalManager();
try{
globalManager.removeDownloadManager(download_manager, delete_torrent, delete_data);
}catch( GlobalManagerDownloadRemovalVetoException e ){
throw( new DownloadRemovalVetoException( e.getMessage()));
}
}else{
throw( new DownloadRemovalVetoException( MessageText.getString("plugin.download.remove.veto.notstopped")));
}
}
public boolean
canBeRemoved()
throws DownloadRemovalVetoException
{
int dl_state = download_manager.getState();
if ( dl_state == DownloadManager.STATE_STOPPED ||
dl_state == DownloadManager.STATE_ERROR ||
dl_state == DownloadManager.STATE_QUEUED ){
GlobalManager globalManager = download_manager.getGlobalManager();
try{
globalManager.canDownloadManagerBeRemoved(download_manager, false, false);
}catch( GlobalManagerDownloadRemovalVetoException e ){
throw( new DownloadRemovalVetoException( e.getMessage(),e.isSilent()));
}
}else{
throw( new DownloadRemovalVetoException( MessageText.getString("plugin.download.remove.veto.notstopped")));
}
return( true );
}
public DownloadStats
getStats()
{
return( download_stats );
}
public boolean
isComplete()
{
return download_manager.isDownloadComplete(false);
}
public boolean isComplete(boolean bIncludeDND) {
return download_manager.isDownloadComplete(bIncludeDND);
}
public boolean
isChecking()
{
return( download_stats.getCheckingDoneInThousandNotation() != -1 );
}
protected void
isRemovable()
throws DownloadRemovalVetoException
{
// no sync required, see update code
for (int i=0;i<removal_listeners.size();i++){
try{
((DownloadWillBeRemovedListener)removal_listeners.get(i)).downloadWillBeRemoved(this);
}catch( DownloadRemovalVetoException e ){
throw( e );
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
protected void
destroy()
{
download_manager.removeListener( this );
}
// DownloadManagerListener methods
public void
stateChanged(
DownloadManager manager,
int state )
{
int prev_state = latest_state;
latest_state = convertState(state);
// System.out.println("Plug: dl = " + getName() + ", prev = " + prev_state + ", curr = " + latest_state + ", signalled state = " + state);
boolean curr_forcedStart = isForceStart();
if ( prev_state != latest_state || latest_forcedStart != curr_forcedStart ){
latest_forcedStart = curr_forcedStart;
for (int i=0;i<listeners.size();i++){
try{
long startTime = SystemTime.getCurrentTime();
DownloadListener listener = (DownloadListener)listeners.get(i);
listener.stateChanged( this, prev_state, latest_state );
long diff = SystemTime.getCurrentTime() - startTime;
if (diff > 1000) {
System.out.println("Plugin should move long processes (" + diff
+ "ms) off of Download's stateChanged listener trigger. "
+ listener);
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
}
public void
downloadComplete(DownloadManager manager)
{
}
public void
completionChanged(
DownloadManager manager,
boolean bCompleted)
{
}
public void
filePriorityChanged( DownloadManager download, org.gudy.azureus2.core3.disk.DiskManagerFileInfo file )
{
}
public void
positionChanged(
DownloadManager download,
int oldPosition,
int newPosition)
{
for (int i = 0; i < listeners.size(); i++) {
try {
long startTime = SystemTime.getCurrentTime();
DownloadListener listener = (DownloadListener)listeners.get(i);
listener.positionChanged(this, oldPosition, newPosition);
long diff = SystemTime.getCurrentTime() - startTime;
if (diff > 1000) {
System.out.println("Plugin should move long processes (" + diff
+ "ms) off of Download's positionChanged listener trigger. "
+ listener);
}
} catch (Throwable e) {
Debug.printStackTrace( e );
}
}
}
public void
addListener(
DownloadListener l )
{
try{
listeners_mon.enter();
List new_listeners = new ArrayList( listeners );
new_listeners.add(l);
listeners = new_listeners;
}finally{
listeners_mon.exit();
}
}
public void
removeListener(
DownloadListener l )
{
try{
listeners_mon.enter();
List new_listeners = new ArrayList(listeners);
new_listeners.remove(l);
listeners = new_listeners;
}finally{
listeners_mon.exit();
}
}
public void addAttributeListener(DownloadAttributeListener listener, TorrentAttribute attr, int event_type) {
try {
this.attr_listener_mon.enter();
if (this.attribute_listener_bridge == null) {
this.attribute_listener_bridge = new DownloadAttributeListenerBridge();
this.addPropertyListener(this.attribute_listener_bridge);
}
Map attr_map = this.getAttributeMapForType(event_type);
List listener_list = (List)attr_map.get(attr);
if (listener_list == null) {
listener_list = new ArrayList();
attr_map.put(attr, listener_list);
}
listener_list.add(listener);
}
finally {this.attr_listener_mon.exit();}
}
public void removeAttributeListener(DownloadAttributeListener listener, TorrentAttribute attr, int event_type) {
try {
this.attr_listener_mon.enter();
Map attr_map = this.getAttributeMapForType(event_type);
List listener_list = (List)attr_map.get(attr);
// Remove the listener, and clear up the mapping list if need be.
if (listener_list != null) {
listener_list.remove(listener);
if (listener_list.isEmpty()) {attr_map.remove(attr);}
}
// If both mappings are empty, destroy the bridge.
if (attribute_listener_bridge != null && read_attribute_listeners.isEmpty() && write_attribute_listeners.isEmpty()) {
this.removePropertyListener(attribute_listener_bridge);
this.attribute_listener_bridge = null;
}
}
finally {this.attr_listener_mon.exit();}
}
public DownloadAnnounceResult
getLastAnnounceResult()
{
TRTrackerAnnouncer tc = download_manager.getTrackerClient();
if ( tc != null ){
last_announce_result.setContent( tc.getLastResponse());
}
return( last_announce_result );
}
public DownloadScrapeResult
getLastScrapeResult()
{
TRTrackerScraperResponse response = download_manager.getTrackerScrapeResponse();
last_scrape_result.setContent( response );
return( last_scrape_result );
}
public void
scrapeResult(
TRTrackerScraperResponse response )
{
last_scrape_result.setContent( response );
for (int i=0;i<tracker_listeners.size();i++){
try{
((DownloadTrackerListener)tracker_listeners.get(i)).scrapeResult( last_scrape_result );
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
// Used by DownloadEventNotifierImpl.
void announceTrackerResultsToListener(DownloadTrackerListener l) {
l.announceResult(last_announce_result);
l.scrapeResult(last_scrape_result);
}
public void
announceResult(
TRTrackerAnnouncerResponse response )
{
last_announce_result.setContent( response );
List tracker_listeners_ref = tracker_listeners;
for (int i=0;i<tracker_listeners_ref.size();i++){
try{
((DownloadTrackerListener)tracker_listeners_ref.get(i)).announceResult( last_announce_result );
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
public void
setAnnounceResult(
DownloadAnnounceResult result )
{
download_manager.setAnnounceResult( result );
}
public void
setScrapeResult(
DownloadScrapeResult result )
{
download_manager.setScrapeResult( result );
}
public void
stateChanged(
DownloadManagerState state,
DownloadManagerStateEvent event )
{
final int type = event.getType();
if ( type == DownloadManagerStateEvent.ET_ATTRIBUTE_WRITTEN ||
type == DownloadManagerStateEvent.ET_ATTRIBUTE_WILL_BE_READ ){
String name = (String)event.getData();
List property_listeners_ref = property_listeners;
final TorrentAttribute attr = convertAttribute( name );
if ( attr != null ){
for (int i=0;i<property_listeners_ref.size();i++){
try{
((DownloadPropertyListener)property_listeners_ref.get(i)).propertyChanged(
this,
new DownloadPropertyEvent()
{
public int
getType()
{
return( type==DownloadManagerStateEvent.ET_ATTRIBUTE_WRITTEN
?DownloadPropertyEvent.PT_TORRENT_ATTRIBUTE_WRITTEN
:DownloadPropertyEvent.PT_TORRENT_ATTRIBUTE_WILL_BE_READ );
}
public Object
getData()
{
return( attr );
}
});
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
}
}
public void
addPropertyListener(
DownloadPropertyListener l )
{
try{
tracker_listeners_mon.enter();
List new_property_listeners = new ArrayList( property_listeners );
new_property_listeners.add( l );
property_listeners = new_property_listeners;
if ( property_listeners.size() == 1 ){
download_manager.getDownloadState().addListener( this );
}
}finally{
tracker_listeners_mon.exit();
}
}
public void
removePropertyListener(
DownloadPropertyListener l )
{
try{
tracker_listeners_mon.enter();
List new_property_listeners = new ArrayList( property_listeners );
new_property_listeners.remove( l );
property_listeners = new_property_listeners;
if ( property_listeners.size() == 0 ){
download_manager.getDownloadState().removeListener( this );
}
}finally{
tracker_listeners_mon.exit();
}
}
public void
torrentChanged()
{
TRTrackerAnnouncer client = download_manager.getTrackerClient();
if ( client != null ){
client.resetTrackerUrl(true);
}
}
public void
addTrackerListener(
DownloadTrackerListener l )
{
addTrackerListener(l, true);
}
public void
addTrackerListener(
DownloadTrackerListener l,
boolean immediateTrigger )
{
try{
tracker_listeners_mon.enter();
List new_tracker_listeners = new ArrayList( tracker_listeners );
new_tracker_listeners.add( l );
tracker_listeners = new_tracker_listeners;
if ( tracker_listeners.size() == 1 ){
download_manager.addTrackerListener( this );
}
}finally{
tracker_listeners_mon.exit();
}
if (immediateTrigger) {this.announceTrackerResultsToListener(l);}
}
public void
removeTrackerListener(
DownloadTrackerListener l )
{
try{
tracker_listeners_mon.enter();
List new_tracker_listeners = new ArrayList( tracker_listeners );
new_tracker_listeners.remove( l );
tracker_listeners = new_tracker_listeners;
if ( tracker_listeners.size() == 0 ){
download_manager.removeTrackerListener( this );
}
}finally{
tracker_listeners_mon.exit();
}
}
public void
addDownloadWillBeRemovedListener(
DownloadWillBeRemovedListener l )
{
try{
removal_listeners_mon.enter();
List new_removal_listeners = new ArrayList( removal_listeners );
new_removal_listeners.add(l);
removal_listeners = new_removal_listeners;
}finally{
removal_listeners_mon.exit();
}
}
public void
removeDownloadWillBeRemovedListener(
DownloadWillBeRemovedListener l )
{
try{
removal_listeners_mon.enter();
List new_removal_listeners = new ArrayList( removal_listeners );
new_removal_listeners.remove(l);
removal_listeners = new_removal_listeners;
}finally{
removal_listeners_mon.exit();
}
}
public void
addPeerListener(
DownloadPeerListener l )
{
try{
peer_listeners_mon.enter();
List new_peer_listeners = new ArrayList( peer_listeners );
new_peer_listeners.add( l );
peer_listeners = new_peer_listeners;
if ( peer_listeners.size() == 1 ){
download_manager.addPeerListener( this );
}
}finally{
peer_listeners_mon.exit();
}
}
public void
removePeerListener(
DownloadPeerListener l )
{
try{
peer_listeners_mon.enter();
List new_peer_listeners = new ArrayList( peer_listeners );
new_peer_listeners.remove( l );
peer_listeners = new_peer_listeners;
if ( peer_listeners.size() == 0 ){
download_manager.removePeerListener( this );
}
}finally{
peer_listeners_mon.exit();
}
}
public boolean
activateRequest(
final int count )
{
DownloadActivationEvent event =
new DownloadActivationEvent()
{
public Download
getDownload()
{
return( DownloadImpl.this );
}
public int
getActivationCount()
{
return( count );
}
};
for (Iterator it=activation_listeners.iterator();it.hasNext();){
try{
DownloadActivationListener listener = (DownloadActivationListener)it.next();
if ( listener.activationRequested( event )){
return( true );
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
return( false );
}
public DownloadActivationEvent
getActivationState()
{
return( activation_state );
}
public void
addActivationListener(
DownloadActivationListener l )
{
try{
peer_listeners_mon.enter();
activation_listeners.add( l );
if ( activation_listeners.size() == 1 ){
download_manager.addActivationListener( this );
}
}finally{
peer_listeners_mon.exit();
}
}
public void
removeActivationListener(
DownloadActivationListener l )
{
try{
peer_listeners_mon.enter();
activation_listeners.remove( l );
if ( activation_listeners.size() == 0 ){
download_manager.removeActivationListener( this );
}
}finally{
peer_listeners_mon.exit();
}
}
public void
peerManagerWillBeAdded(
PEPeerManager manager )
{
}
public void
peerManagerAdded(
PEPeerManager manager )
{
if ( peer_listeners.size() > 0 ){
PeerManager pm = PeerManagerImpl.getPeerManager( manager);
for (int i=0;i<peer_listeners.size();i++){
((DownloadPeerListener)peer_listeners.get(i)).peerManagerAdded( this, pm );
}
}
}
public void
peerManagerRemoved(
PEPeerManager manager )
{
if ( peer_listeners.size() > 0 ){
PeerManager pm = PeerManagerImpl.getPeerManager( manager);
for (int i=0;i<peer_listeners.size();i++){
((DownloadPeerListener)peer_listeners.get(i)).peerManagerRemoved( this, pm );
}
}
}
public PeerManager
getPeerManager()
{
PEPeerManager pm = download_manager.getPeerManager();
if ( pm == null ){
return( null );
}
return( PeerManagerImpl.getPeerManager( pm));
}
public DiskManager
getDiskManager()
{
PeerManager pm = getPeerManager();
if ( pm != null ){
return( pm.getDiskManager());
}
return( null );
}
public DiskManagerFileInfo[]
getDiskManagerFileInfo()
{
org.gudy.azureus2.core3.disk.DiskManagerFileInfo[] info = download_manager.getDiskManagerFileInfo();
if ( info == null ){
return( new DiskManagerFileInfo[0] );
}
DiskManagerFileInfo[] res = new DiskManagerFileInfo[info.length];
for (int i=0;i<res.length;i++){
res[i] = new DiskManagerFileInfoImpl( this, info[i] );
}
return( res );
}
public void
peerAdded(
PEPeer peer )
{
}
public void
peerRemoved(
PEPeer peer )
{
}
public void
setMaximumDownloadKBPerSecond(
int kb )
{
if(kb==-1){
Debug.out("setMaximiumDownloadKBPerSecond got value (-1) ZERO_DOWNLOAD. (-1)"+
"does not work through this method, use getDownloadRateLimitBytesPerSecond() instead.");
}//if
download_manager.getStats().setDownloadRateLimitBytesPerSecond( kb < 0 ? 0 : kb*1024 );
}
public int
getMaximumDownloadKBPerSecond()
{
return( download_manager.getStats().getDownloadRateLimitBytesPerSecond() /1024 );
}
public int getUploadRateLimitBytesPerSecond() {
return download_manager.getStats().getUploadRateLimitBytesPerSecond();
}
public void setUploadRateLimitBytesPerSecond( int max_rate_bps ) {
download_manager.getStats().setUploadRateLimitBytesPerSecond( max_rate_bps );
}
public int getDownloadRateLimitBytesPerSecond() {
return download_manager.getStats().getDownloadRateLimitBytesPerSecond();
}
public void setDownloadRateLimitBytesPerSecond( int max_rate_bps ) {
download_manager.getStats().setDownloadRateLimitBytesPerSecond( max_rate_bps );
}
public int getSeedingRank() {
return download_manager.getSeedingRank();
}
public void setSeedingRank(int rank) {
download_manager.setSeedingRank(rank);
}
public String
getSavePath()
{
return( download_manager.getSaveLocation().toString());
}
public void
moveDataFiles(
File new_parent_dir )
throws DownloadException
{
try{
download_manager.moveDataFiles( new_parent_dir );
}catch( DownloadManagerException e ){
throw( new DownloadException("move operation failed", e ));
}
}
public void moveDataFiles(File new_parent_dir, String new_name)
throws DownloadException
{
try{
download_manager.moveDataFiles( new_parent_dir, new_name );
}catch( DownloadManagerException e ){
throw( new DownloadException("move / rename operation failed", e ));
}
}
public void renameDownload(String new_name) throws DownloadException {
try {download_manager.renameDownload(new_name);}
catch (DownloadManagerException e) {
throw new DownloadException("rename operation failed", e);
}
}
public void
moveTorrentFile(
File new_parent_dir )
throws DownloadException
{
try{
download_manager.moveTorrentFile( new_parent_dir );
}catch( DownloadManagerException e ){
throw( new DownloadException("move operation failed", e ));
}
}
public File[] calculateDefaultPaths(boolean for_moving) {
return download_manager.calculateDefaultPaths(for_moving);
}
public boolean isInDefaultSaveDir() {
return download_manager.isInDefaultSaveDir();
}
public void
requestTrackerAnnounce()
{
download_manager.requestTrackerAnnounce( false );
}
public void
requestTrackerAnnounce(
boolean immediate )
{
download_manager.requestTrackerAnnounce( immediate );
}
public void
requestTrackerScrape(
boolean immediate )
{
download_manager.requestTrackerScrape( immediate );
}
public byte[] getDownloadPeerId() {
TRTrackerAnnouncer announcer = download_manager.getTrackerClient();
if(announcer == null) return null;
return announcer.getPeerId();
}
public boolean isMessagingEnabled() { return download_manager.isExtendedMessagingEnabled(); }
public void setMessagingEnabled( boolean enabled ) {
throw new RuntimeException("setMessagingEnabled is in the process of being removed - if you are seeing this error, let the Azureus developers know that you need this method to stay!");
//download_manager.setAZMessagingEnabled( enabled );
}
public void setSessionAuthenticator( SessionAuthenticator auth ) {
//TODO
}
// Deprecated methods
public int getPriority() {
return 0;
}
public boolean isPriorityLocked() {
return false;
}
public void setPriority(int priority) {
}
public boolean isRemoved() {
return( download_manager.isDestroyed());
}
// Pass LogRelation off to core objects
/* (non-Javadoc)
* @see org.gudy.azureus2.core3.logging.LogRelation#getLogRelationText()
*/
public String getRelationText() {
return propogatedRelationText(download_manager);
}
/* (non-Javadoc)
* @see org.gudy.azureus2.core3.logging.LogRelation#getQueryableInterfaces()
*/
public Object[] getQueryableInterfaces() {
return new Object[] { download_manager };
}
private class DownloadAttributeListenerBridge implements DownloadPropertyListener {
public void propertyChanged(Download d, DownloadPropertyEvent e) {
Map attr_listener_map = getAttributeMapForType(e.getType());
List listeners = (List)attr_listener_map.get(e.getData());
if (listeners == null) {return;}
try {
attr_listener_mon.enter();
ArrayList listener_ref = new ArrayList(listeners);
for (int i=0; i<listener_ref.size(); i++) {
DownloadAttributeListener dal = (DownloadAttributeListener)listener_ref.get(i);
try {
dal.attributeEventOccurred(d, (TorrentAttribute)e.getData(), e.getType());
}
catch (Throwable t) {Debug.printStackTrace(t);}
}
}
finally {attr_listener_mon.exit();}
}
}
private Map getAttributeMapForType(int event_type) {
return event_type == DownloadPropertyEvent.PT_TORRENT_ATTRIBUTE_WILL_BE_READ ? read_attribute_listeners : write_attribute_listeners;
}
}