package org.gudy.azureus2.core3.download.impl; ///* // * Created on 29-Jul-2005 // * Created by Paul Gardner // * Copyright (C) 2005, 2006 Aelitis, All Rights Reserved. // * // * 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. // * // * AELITIS, SAS au capital de 46,603.30 euros // * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. // * // */ // //package org.gudy.azureus2.core3.download.impl; // //import java.io.File; //import java.io.IOException; //import java.net.InetSocketAddress; //import java.util.*; // //import org.gudy.azureus2.core3.config.COConfigurationManager; //import org.gudy.azureus2.core3.disk.*; //import org.gudy.azureus2.core3.download.DownloadManager; //import org.gudy.azureus2.core3.download.DownloadManagerDiskListener; //import org.gudy.azureus2.core3.download.DownloadManagerState; //import org.gudy.azureus2.core3.download.ForceRecheckListener; //import org.gudy.azureus2.core3.global.GlobalManager; //import org.gudy.azureus2.core3.global.GlobalManagerStats; //import org.gudy.azureus2.core3.internat.MessageText; //import org.gudy.azureus2.core3.logging.LogEvent; //import org.gudy.azureus2.core3.logging.LogIDs; //import org.gudy.azureus2.core3.logging.LogRelation; //import org.gudy.azureus2.core3.logging.Logger; //import org.gudy.azureus2.core3.peer.*; //import org.gudy.azureus2.core3.torrent.TOTorrent; //import org.gudy.azureus2.core3.torrent.TOTorrentException; //import org.gudy.azureus2.core3.torrent.TOTorrentFile; //import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer; //import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerDataProvider; //import org.gudy.azureus2.core3.tracker.client.TRTrackerScraperResponse; //import org.gudy.azureus2.core3.util.*; //import org.gudy.azureus2.plugins.network.ConnectionManager; // //import com.aelitis.azureus.core.AzureusCoreFactory; //import com.aelitis.azureus.core.networkmanager.LimitedRateGroup; //import com.aelitis.azureus.core.networkmanager.NetworkConnection; //import com.aelitis.azureus.core.peermanager.PeerManager; //import com.aelitis.azureus.core.peermanager.PeerManagerRegistration; //import com.aelitis.azureus.core.peermanager.PeerManagerRegistrationAdapter; //import com.aelitis.azureus.core.peermanager.peerdb.PeerItemFactory; //import com.aelitis.azureus.core.util.bloom.BloomFilter; //import com.aelitis.azureus.core.util.bloom.BloomFilterFactory; //import com.aelitis.azureus.plugins.extseed.ExternalSeedPlugin; // //public class //DownloadManagerController // extends LogRelation // implements PEPeerManagerAdapter, PeerManagerRegistrationAdapter //{ // private static long STATE_FLAG_HASDND = 0x01; // private static long STATE_FLAG_COMPLETE_NO_DND = 0x02; // // private static long skeleton_builds; // // private static ExternalSeedPlugin ext_seed_plugin; // private static boolean ext_seed_plugin_tried; // // private static ExternalSeedPlugin // getExternalSeedPlugin() // { // if ( !ext_seed_plugin_tried ){ // // ext_seed_plugin_tried = true; // // try { // org.gudy.azureus2.plugins.PluginInterface ext_pi = AzureusCoreFactory.getSingleton().getPluginManager().getPluginInterfaceByClass(ExternalSeedPlugin.class); // if (ext_pi != null) { // ext_seed_plugin = (ExternalSeedPlugin)ext_pi.getPlugin(); // } // // }catch (Throwable e){ // // Debug.printStackTrace( e ); // } // } // // return( ext_seed_plugin ); // } // // // DISK listeners // // private static final int LDT_DL_ADDED = 1; // private static final int LDT_DL_REMOVED = 2; // // private static ListenerManager disk_listeners_agregator = ListenerManager.createAsyncManager( // "DMC:DiskListenAgregatorDispatcher", // new ListenerManagerDispatcher() // { // public void // dispatch( // Object _listener, // int type, // Object value ) // { // DownloadManagerDiskListener listener = (DownloadManagerDiskListener)_listener; // // if ( type == LDT_DL_ADDED ){ // // listener.diskManagerAdded((DiskManager)value); // // }else if ( type == LDT_DL_REMOVED ){ // // listener.diskManagerRemoved((DiskManager)value); // } // } // }); // // private ListenerManager disk_listeners = ListenerManager.createManager( // "DMC:DiskListenDispatcher", // new ListenerManagerDispatcher() // { // public void // dispatch( // Object listener, // int type, // Object value ) // { // disk_listeners_agregator.dispatch( listener, type, value ); // } // }); // // private AEMonitor disk_listeners_mon = new AEMonitor( "DownloadManagerController:DL" ); // // protected AEMonitor this_mon = new AEMonitor( "DownloadManagerController" ); // protected AEMonitor state_mon = new AEMonitor( "DownloadManagerController:State" ); // // private DownloadManagerImpl download_manager; // private DownloadManagerStatsImpl stats; // // // these are volatile as we want to ensure that if a state is read it is always the // // most up to date value available (as we don't synchronize state read - see below // // for comments) // // private volatile int state_set_by_method = DownloadManager.STATE_START_OF_DAY; // private volatile int substate; // private volatile boolean force_start; // // // to try and ensure people don't start using disk_manager without properly considering its // // access implications we've given it a silly name // // private volatile DiskManager disk_manager_use_accessors; // private DiskManagerListener disk_manager_listener_use_accessors; // // private FileInfoFacadeSet fileFacadeSet = new FileInfoFacadeSet(); // private boolean files_facade_destroyed; // // private boolean cached_complete_excluding_dnd; // private boolean cached_has_dnd_files; // private boolean cached_values_set; // // private PeerManagerRegistration peer_manager_registration; // private PEPeerManager peer_manager; // // private List external_rate_limiters_cow; // // private String errorDetail; // // private GlobalManagerStats global_stats; // // private boolean bInitialized = false; // // private long data_send_rate_at_close; // // private static final int ACTIVATION_REBUILD_TIME = 10*60*1000; // private static final int BLOOM_SIZE = 64; // private volatile BloomFilter activation_bloom; // private volatile long activation_bloom_create_time = SystemTime.getCurrentTime(); // private volatile int activation_count; // private volatile long activation_count_time; // // private boolean piece_checking_enabled = true; // // private long priority_connection_count; // // // protected // DownloadManagerController( // DownloadManagerImpl _download_manager ) // { // download_manager = _download_manager; // // GlobalManager gm = download_manager.getGlobalManager(); // // global_stats = gm.getStats(); // // stats = (DownloadManagerStatsImpl)download_manager.getStats(); // // cached_values_set = false; // } // // protected void // setInitialState( // int initial_state ) // { // // only take note if there's been no errors // // bInitialized = true; // // if ( getState() == DownloadManager.STATE_START_OF_DAY ){ // // setState( initial_state, true ); // } // // // TOTorrent torrent = download_manager.getTorrent(); // // if (torrent != null) { // // try{ // peer_manager_registration = PeerManager.getSingleton().registerLegacyManager( torrent.getHashWrapper(), this ); // // }catch( TOTorrentException e ){ // // Debug.printStackTrace(e); // } // } // // DownloadManagerState state = download_manager.getDownloadState(); // if (state.parameterExists(DownloadManagerState.PARAM_DND_FLAGS)) { // long flags = state.getLongParameter(DownloadManagerState.PARAM_DND_FLAGS); // cached_complete_excluding_dnd = (flags & STATE_FLAG_COMPLETE_NO_DND) != 0; // cached_has_dnd_files = (flags & STATE_FLAG_HASDND) != 0; // cached_values_set = true; // } // } // // public void // startDownload( // TRTrackerAnnouncer tracker_client ) // { // DiskManager dm; // // try{ // this_mon.enter(); // // if ( getState() != DownloadManager.STATE_READY ){ // // Debug.out( "DownloadManagerController::startDownload state must be ready, " + getState()); // // setFailed( "Inconsistent download state: startDownload, state = " + getState()); // // return; // } // // if ( tracker_client == null ){ // // Debug.out( "DownloadManagerController:startDownload: tracker_client is null" ); // // // one day we should really do a proper state machine for this. In the meantime... // // probably caused by a "stop" during initialisation, I've reproduced it once or twice // // in my life... Tidy things up so we don't sit here in a READ state that can't // // be started. // // stopIt( DownloadManager.STATE_STOPPED, false, false ); // // return; // } // // if ( peer_manager != null ){ // // Debug.out( "DownloadManagerController::startDownload: peer manager not null" ); // // // try and continue.... // // peer_manager.stopAll(); // // peer_manager = null; // } // // dm = getDiskManager(); // // if ( dm == null ){ // // Debug.out( "DownloadManagerController::startDownload: disk manager is null" ); // // return; // } // // setState( DownloadManager.STATE_DOWNLOADING, false ); // // }finally{ // // this_mon.exit(); // // } // // // make sure it is started before making it "visible" // // final PEPeerManager temp = PEPeerManagerFactory.create( tracker_client.getPeerId(), this, dm ); // // download_manager.informWillBeStarted( temp ); // // temp.start(); // // //The connection to the tracker // // tracker_client.setAnnounceDataProvider( // new TRTrackerAnnouncerDataProvider() // { // private long last_reported_total_received; // private long last_reported_total_received_data; // private long last_reported_total_received_discard; // private long last_reported_total_received_failed; // // public String // getName() // { // return( getDisplayName()); // } // // public long // getTotalSent() // { // return(temp.getStats().getTotalDataBytesSentNoLan()); // } // public long // getTotalReceived() // { // long received = temp.getStats().getTotalDataBytesReceivedNoLan(); // long discarded = temp.getStats().getTotalDiscarded(); // long failed = temp.getStats().getTotalHashFailBytes(); // // long verified = received - ( discarded + failed ); // // verified -= temp.getHiddenBytes(); // // // ensure we don't go backwards. due to lack of atomicity of updates and possible // // miscounting somewhere we have seen this occur // // if ( verified < last_reported_total_received ){ // // verified = last_reported_total_received; // // // use -1 as indicator that we've reported this event // // if ( last_reported_total_received_data != -1 ){ // // /* // Debug.out( // getDisplayName() + ": decrease in overall downloaded - " + // "data=" + received + "/" + last_reported_total_received_data + // ",discard=" + discarded + "/" + last_reported_total_received_discard + // ",fail=" + failed + "/" + last_reported_total_received_failed ); // */ // // last_reported_total_received_data = -1; // } // }else{ // // last_reported_total_received = verified; // // last_reported_total_received_data = received; // last_reported_total_received_discard = discarded; // last_reported_total_received_failed = failed; // } // // return( verified < 0?0:verified ); // } // // public long // getRemaining() // { // return( Math.max( temp.getRemaining(), temp.getHiddenBytes())); // } // // public long // getFailedHashCheck() // { // return( temp.getStats().getTotalHashFailBytes()); // } // // public String // getExtensions() // { // return( getTrackerClientExtensions()); // } // // public int // getMaxNewConnectionsAllowed() // { // return( temp.getMaxNewConnectionsAllowed()); // } // // public int // getUploadSpeedKBSec( // boolean estimate ) // { // long current_local = stats.getDataSendRate(); // // if ( estimate ){ // // // see if we have an old value from previous stop/start // // current_local = data_send_rate_at_close; // // if ( current_local == 0 ){ // // int current_global = global_stats.getDataSendRate(); // // int old_global = global_stats.getDataSendRateAtClose(); // // if ( current_global < old_global ){ // // current_global = old_global; // } // // List managers = download_manager.getGlobalManager().getDownloadManagers(); // // int num_dls = 0; // // // be optimistic and share out the bytes between non-seeds // // for (int i=0;i<managers.size();i++){ // // DownloadManager dm = (DownloadManager)managers.get(i); // // if ( dm.getStats().getDownloadCompleted( false ) == 1000 ){ // // continue; // } // // int state = dm.getState(); // // if ( state != DownloadManager.STATE_ERROR && // state != DownloadManager.STATE_STOPPING && // state != DownloadManager.STATE_STOPPED ){ // // num_dls++; // } // } // // if ( num_dls == 0 ){ // // current_local = current_global; // }else{ // // current_local = current_global/num_dls; // } // } // } // // return((int)((current_local+1023)/1024 )); // } // // public int // getCryptoLevel() // { // return( download_manager.getCryptoLevel()); // } // // public void // setPeerSources( // String[] allowed_sources ) // { // DownloadManagerState dms = download_manager.getDownloadState(); // // String[] sources = PEPeerSource.PS_SOURCES; // // for (int i=0;i<sources.length;i++){ // // String s = sources[i]; // // boolean ok = false; // // for (int j=0;j<allowed_sources.length;j++){ // // if ( s.equals( allowed_sources[j] )){ // // ok = true; // // break; // } // } // // if ( !ok ){ // // dms.setPeerSourcePermitted( s, false ); // } // } // // PEPeerManager pm = getPeerManager(); // // if ( pm != null ){ // // Set<String> allowed = new HashSet<String>(); // // allowed.addAll( Arrays.asList( allowed_sources )); // // Iterator<PEPeer> it = pm.getPeers().iterator(); // // while( it.hasNext()){ // // PEPeer peer = it.next(); // // if ( !allowed.contains( peer.getPeerSource())){ // // pm.removePeer( peer, "Peer source not permitted" ); // } // } // } // } // // public boolean // isPeerSourceEnabled( // String peer_source ) // { // return( DownloadManagerController.this.isPeerSourceEnabled( peer_source )); // } // }); // // // List limiters; // // try{ // this_mon.enter(); // // peer_manager = temp; // // limiters = external_rate_limiters_cow; // // }finally{ // // this_mon.exit(); // } // // if ( limiters != null ){ // // for (int i=0;i<limiters.size();i++){ // // Object[] entry = (Object[])limiters.get(i); // // temp.addRateLimiter((LimitedRateGroup)entry[0],((Boolean)entry[1]).booleanValue()); // } // } // // // Inform only after peer_manager.start(), because it // // may have switched it to STATE_SEEDING (in which case we don't need to // // inform). // // if (getState() == DownloadManager.STATE_DOWNLOADING) { // // download_manager.informStateChanged(); // } // // download_manager.informStarted( temp ); // } // // // // // public void // initializeDiskManager( // final boolean open_for_seeding ) // { // initializeDiskManagerSupport( // DownloadManager.STATE_INITIALIZED, // new DiskManagerListener() // { // public void // stateChanged( // int oldDMState, // int newDMState ) // { // DiskManager dm; // // try{ // this_mon.enter(); // // dm = getDiskManager(); // // if ( dm == null ){ // // // already been cleared down // // return; // } // // }finally{ // this_mon.exit(); // } // // try{ // if ( newDMState == DiskManager.FAULTY ){ // // setFailed( dm.getErrorMessage()); // } // // if ( oldDMState == DiskManager.CHECKING && newDMState != DiskManager.CHECKING ){ // // // good time to trigger minimum file info fixup as the disk manager's // // files are now in a good state // // fileFacadeSet.makeSureFilesFacadeFilled(true); // // stats.setDownloadCompleted(stats.getDownloadCompleted(true)); // // download_manager.setAssumedComplete(isDownloadComplete(false)); // } // // if ( newDMState == DiskManager.READY ){ // // int completed = stats.getDownloadCompleted(false); // // if ( stats.getTotalDataBytesReceived() == 0 && // stats.getTotalDataBytesSent() == 0 && // stats.getSecondsDownloading() == 0 ){ // // if ( completed < 1000 ){ // // if ( open_for_seeding ){ // // setFailed( "File check failed" ); // // download_manager.getDownloadState().clearResumeData(); // // }else{ // // // make up some sensible "downloaded" figure for torrents that have been re-added to Azureus // // and resumed // // // // assume downloaded = uploaded, optimistic but at least results in // // future share ratios relevant to amount up/down from now on // // see bug 1077060 // // long amount_downloaded = (completed*dm.getTotalLength())/1000; // // stats.setSavedDownloadedUploaded( amount_downloaded, amount_downloaded ); // } // }else{ // // see GlobalManager for comment on this // // int dl_copies = COConfigurationManager.getIntParameter("StartStopManager_iAddForSeedingDLCopyCount"); // // if ( dl_copies > 0 ){ // // stats.setSavedDownloadedUploaded( download_manager.getSize()*dl_copies, stats.getTotalDataBytesSent()); // } // // download_manager.getDownloadState().setFlag( DownloadManagerState.FLAG_ONLY_EVER_SEEDED, true ); // } // } // // /* all initialization should be done here (Disk- and DownloadManager). // * assume this download is complete and won't recieve any modifications until it is stopped again // * or the user fiddles on the knobs // * discard fluff once tentatively, will save memory for many active, seeding torrent-cases // */ // if(completed == 1000) // download_manager.getDownloadState().discardFluff(); // } // }finally{ // // download_manager.informStateChanged(); // } // } // // public void // filePriorityChanged( // DiskManagerFileInfo file ) // { // download_manager.informPriorityChange( file ); // } // // public void // pieceDoneChanged( // DiskManagerPiece piece ) // { // } // // public void // fileAccessModeChanged( // DiskManagerFileInfo file, // int old_mode, // int new_mode ) // { // } // }); // } // // protected void // initializeDiskManagerSupport( // int initialising_state, // DiskManagerListener listener ) // { // try{ // this_mon.enter(); // // int entry_state = getState(); // // if ( entry_state != DownloadManager.STATE_WAITING && // entry_state != DownloadManager.STATE_STOPPED && // entry_state != DownloadManager.STATE_QUEUED && // entry_state != DownloadManager.STATE_ERROR ){ // // Debug.out( "DownloadManagerController::initializeDiskManager: Illegal initialize state, " + entry_state ); // // setFailed( "Inconsistent download state: initSupport, state = " + entry_state ); // // return; // } // // DiskManager old_dm = getDiskManager(); // // if ( old_dm != null ){ // // Debug.out( "DownloadManagerController::initializeDiskManager: disk manager is not null" ); // // // we shouldn't get here but try to recover the situation // // old_dm.stop( false ); // // setDiskManager( null, null ); // } // // errorDetail = ""; // // setState( initialising_state, false ); // // DiskManager dm = DiskManagerFactory.create( download_manager.getTorrent(), download_manager); // // setDiskManager( dm, listener ); // // }finally{ // // this_mon.exit(); // // download_manager.informStateChanged(); // } // } // // public boolean // canForceRecheck() // { // int state = getState(); // // // gotta check error + disk manager state as error can be generated by both // // an overall error or a running disk manager in faulty state // // return( (state == DownloadManager.STATE_STOPPED ) || // (state == DownloadManager.STATE_QUEUED ) || // (state == DownloadManager.STATE_ERROR && getDiskManager() == null)); // } // // public void // forceRecheck(final ForceRecheckListener l) // { // try{ // this_mon.enter(); // // if ( getDiskManager() != null || !canForceRecheck() ){ // // Debug.out( "DownloadManagerController::forceRecheck: illegal entry state" ); // // return; // } // // final int start_state = DownloadManagerController.this.getState(); // // // remove resume data // // download_manager.getDownloadState().clearResumeData(); // // // For extra protection from a plugin stopping a checking torrent, // // fake a forced start. // // final boolean wasForceStarted = force_start; // // force_start = true; // // // if a file has been deleted we want this recheck to recreate the file and mark // // it as 0%, not fail the recheck. Otherwise the only way of recovering is to remove and // // re-add the torrent // // download_manager.setDataAlreadyAllocated( false ); // // initializeDiskManagerSupport( // DownloadManager.STATE_CHECKING, // new forceRecheckDiskManagerListener(wasForceStarted, start_state, l)); // // }finally{ // // this_mon.exit(); // } // } // // public void // setPieceCheckingEnabled( // boolean enabled ) // { // piece_checking_enabled = enabled; // // DiskManager dm = getDiskManager(); // // if ( dm != null ){ // // dm.setPieceCheckingEnabled( enabled ); // } // } // // public void // stopIt( // int _stateAfterStopping, // final boolean remove_torrent, // final boolean remove_data ) // { // long current_up = stats.getDataSendRate(); // // if ( current_up != 0 ){ // // data_send_rate_at_close = current_up; // } // // boolean closing = _stateAfterStopping == DownloadManager.STATE_CLOSED; // // if ( closing ){ // // _stateAfterStopping = DownloadManager.STATE_STOPPED; // } // // final int stateAfterStopping = _stateAfterStopping; // // try{ // this_mon.enter(); // // int state = getState(); // // if ( state == DownloadManager.STATE_STOPPED || // ( state == DownloadManager.STATE_ERROR && getDiskManager() == null )) { // // //already in stopped state, just do removals if necessary // // if( remove_data ){ // // download_manager.deleteDataFiles(); // } // // if( remove_torrent ){ // // download_manager.deleteTorrentFile(); // } // // setState( _stateAfterStopping, false ); // // return; // } // // // if ( state == DownloadManager.STATE_STOPPING){ // // return; // } // // setSubState( _stateAfterStopping ); // // setState( DownloadManager.STATE_STOPPING, false ); // // // // this will run synchronously but on a non-daemon thread so that it will under // // normal circumstances complete, even if we're closing // // // final AESemaphore nd_sem = new AESemaphore( "DM:DownloadManager.NDTR" ); // // NonDaemonTaskRunner.runAsync( // new NonDaemonTask() // { // public Object // run() // { // nd_sem.reserve(); // // return( null ); // } // // public String // getName() // { // return( "Stopping '" + getDisplayName() + "'" ); // } // // }); // // try{ // try{ // // if ( peer_manager != null ){ // // peer_manager.stopAll(); // // stats.saveSessionTotals(); // } // // // do this even if null as it also triggers tracker actions // // download_manager.informStopped( peer_manager, stateAfterStopping==DownloadManager.STATE_QUEUED ); // // peer_manager = null; // // DiskManager dm = getDiskManager(); // // if ( dm != null ){ // // dm.stop( closing ); // // stats.setCompleted(stats.getCompleted()); // stats.setDownloadCompleted(stats.getDownloadCompleted(true)); // // // we don't want to update the torrent if we're seeding // // if ( !download_manager.getAssumedComplete()){ // // download_manager.getDownloadState().save(); // } // // setDiskManager( null, null ); // } // // }finally{ // // force_start = false; // // if( remove_data ){ // // download_manager.deleteDataFiles(); // } // // if( remove_torrent ){ // // download_manager.deleteTorrentFile(); // } // // // only update the state if things haven't gone wrong // // if ( getState() == DownloadManager.STATE_STOPPING ){ // // setState( stateAfterStopping, true ); // } // } // }finally{ // // nd_sem.release(); // } // // }catch( Throwable e ){ // // Debug.printStackTrace( e ); // // }finally{ // // this_mon.exit(); // // download_manager.informStateChanged(); // } // } // // protected void // setStateWaiting() // { // setState(DownloadManager.STATE_WAITING, true ); // } // // public void // setStateFinishing() // { // setState(DownloadManager.STATE_FINISHING, true); // } // // public void // setStateDownloading() // { // if (getState() == DownloadManager.STATE_SEEDING) { // setState(DownloadManager.STATE_DOWNLOADING, true); // } else if (getState() != DownloadManager.STATE_DOWNLOADING) { // Logger.log(new LogEvent(this, LogIDs.CORE, LogEvent.LT_WARNING, // "Trying to set state to downloading when state is not seeding")); // } // } // // // public void // setStateSeeding( // boolean never_downloaded ) // { // // should already be finishing, but make sure (if it already is, there // // won't be a trigger) // setStateFinishing(); // // download_manager.downloadEnded(never_downloaded); // // setState(DownloadManager.STATE_SEEDING, true); // } // // public boolean // isStateSeeding() // { // return( getState() == DownloadManager.STATE_SEEDING ); // } // // protected void // setStateQueued() // { // setState(DownloadManager.STATE_QUEUED, true); // } // // public int // getState() // { // if ( state_set_by_method != DownloadManager.STATE_INITIALIZED ){ // // return( state_set_by_method ); // } // // // we don't want to synchronize here as there are potential deadlock problems // // regarding the DownloadManager::addListener call invoking this method while // // holding the listeners monitor. // // // DiskManager dm = getDiskManager(); // // if ( dm == null){ // // return DownloadManager.STATE_INITIALIZED; // } // // int diskManagerState = dm.getState(); // // if (diskManagerState == DiskManager.INITIALIZING){ // // return DownloadManager.STATE_INITIALIZED; // // }else if (diskManagerState == DiskManager.ALLOCATING){ // // return DownloadManager.STATE_ALLOCATING; // // }else if (diskManagerState == DiskManager.CHECKING){ // // return DownloadManager.STATE_CHECKING; // // }else if (diskManagerState == DiskManager.READY){ // // return DownloadManager.STATE_READY; // // }else if (diskManagerState == DiskManager.FAULTY){ // // return DownloadManager.STATE_ERROR; // } // // return DownloadManager.STATE_ERROR; // } // // protected int // getSubState() // { // if ( state_set_by_method == DownloadManager.STATE_STOPPING ){ // // return( substate ); // }else{ // // return( getState()); // } // } // // private void // setSubState( // int ss ) // { // substate = ss; // } // // /** // * @param _state // * @param _inform_changed trigger informStateChange (which may not trigger // * listeners if state hasn't changed since last trigger) // */ // private void // setState( // int _state, // boolean _inform_changed ) // { // // we bring this call out of the monitor block to prevent a potential deadlock whereby we chain // // state_mon -> this_mon (there exist numerous dependencies this_mon -> state_mon... // // boolean call_filesExist = false; // // try{ // state_mon.enter(); // // int old_state = state_set_by_method; // // // note: there is a DIFFERENCE between the state held on the DownloadManager and // // that reported via getState as getState incorporated DiskManager states when // // the DownloadManager is INITIALIZED // //System.out.println( "DM:setState - " + _state ); // // if ( old_state != _state ){ // // state_set_by_method = _state; // // if ( state_set_by_method != DownloadManager.STATE_QUEUED ){ // // // only maintain this while queued // // activation_bloom = null; // // if ( state_set_by_method == DownloadManager.STATE_STOPPED ){ // // activation_count = 0; // } // } // // if (state_set_by_method == DownloadManager.STATE_QUEUED ){ // // // // don't pick up errors regarding missing data while queued. // // We'll do that when the torrent starts. Saves time at startup // // pick up any errors regarding missing data for queued SEEDING torrents //// if ( download_manager.getAssumedComplete()){ //// //// call_filesExist = true; //// } // // }else if ( state_set_by_method == DownloadManager.STATE_ERROR ){ // // // the process of attempting to start the torrent may have left some empty // // directories created, some users take exception to this. // // the most straight forward way of remedying this is to delete such empty // // folders here // // TOTorrent torrent = download_manager.getTorrent(); // // if ( torrent != null && !torrent.isSimpleTorrent()){ // // File save_dir_file = download_manager.getAbsoluteSaveLocation(); // // if ( save_dir_file != null && save_dir_file.exists() && save_dir_file.isDirectory()){ // // TorrentUtils.recursiveEmptyDirDelete( save_dir_file, false ); // } // } // } // } // }finally{ // // state_mon.exit(); // } // // if ( call_filesExist ){ // // filesExist( true ); // } // // if ( _inform_changed ){ // // download_manager.informStateChanged(); // } // } // // /** // * Stops the current download, then restarts it again. // */ // // public void // restartDownload(boolean forceRecheck) // { // boolean was_force_start = isForceStart(); // // stopIt( DownloadManager.STATE_STOPPED, false, false ); // // if (forceRecheck) { // download_manager.getDownloadState().clearResumeData(); // } // // download_manager.initialize(); // // if ( was_force_start ){ // // setForceStart(true); // } // } // // protected void // destroy() // { // if ( peer_manager_registration != null ){ // // peer_manager_registration.unregister(); // // peer_manager_registration = null; // } // // fileFacadeSet.destroyFileInfo(); // } // // public boolean // isPeerSourceEnabled( // String peer_source ) // { // return( download_manager.getDownloadState().isPeerSourceEnabled( peer_source )); // } // // // secrets for inbound connections, support all // // public byte[][] // getSecrets() // { // TOTorrent torrent = download_manager.getTorrent(); // // try{ // byte[] secret1 = torrent.getHash(); // // try{ // // byte[] secret2 = getSecret2( torrent ); // // return( new byte[][]{ secret1, secret2 }); // // }catch( Throwable e ){ // // Debug.printStackTrace( e ); // // return( new byte[][]{ secret1 } ); // } // // }catch( Throwable e ){ // // Debug.printStackTrace( e ); // // return( new byte[0][] ); // } // } // // // secrets for outbound connections, based on level of target // // public byte[][] // getSecrets( // int crypto_level ) // { // TOTorrent torrent = download_manager.getTorrent(); // // try{ // byte[] secret; // // if ( crypto_level == PeerItemFactory.CRYPTO_LEVEL_1 ){ // // secret = torrent.getHash(); // // }else{ // // secret = getSecret2( torrent ); // } // // return( new byte[][]{ secret }); // // }catch( Throwable e ){ // // Debug.printStackTrace( e ); // // return( new byte[0][] ); // } // } // // protected byte[] // getSecret2( // TOTorrent torrent ) // // throws TOTorrentException // { // Map secrets_map = download_manager.getDownloadState().getMapAttribute( DownloadManagerState.AT_SECRETS ); // // if ( secrets_map == null ){ // // secrets_map = new HashMap(); // // }else{ // // // clone as we can't just update the returned values // // secrets_map = new LightHashMap(secrets_map); // } // // if ( secrets_map.size() == 0 ){ // // secrets_map.put( "p1", torrent.getPieces()[0] ); // // download_manager.getDownloadState().setMapAttribute( DownloadManagerState.AT_SECRETS, secrets_map ); // } // // return((byte[])secrets_map.get( "p1" )); // } // // public boolean // manualRoute( // NetworkConnection connection ) // { // return false; // } // // public long // getRandomSeed() // { // return( download_manager.getDownloadState().getLongParameter( DownloadManagerState.PARAM_RANDOM_SEED )); // } // // public void // addRateLimiter( // LimitedRateGroup group, // boolean upload ) // { // PEPeerManager pm; // // try{ // this_mon.enter(); // // ArrayList new_limiters = new ArrayList( external_rate_limiters_cow==null?1:external_rate_limiters_cow.size()+1); // // if ( external_rate_limiters_cow != null ){ // // new_limiters.addAll( external_rate_limiters_cow ); // } // // new_limiters.add( new Object[]{ group, new Boolean( upload )}); // // external_rate_limiters_cow = new_limiters; // // pm = peer_manager; // // }finally{ // // this_mon.exit(); // } // // if ( pm != null ){ // // pm.addRateLimiter(group, upload); // } // } // // public void // removeRateLimiter( // LimitedRateGroup group, // boolean upload ) // { // PEPeerManager pm; // // try{ // this_mon.enter(); // // if ( external_rate_limiters_cow != null ){ // // ArrayList new_limiters = new ArrayList( external_rate_limiters_cow.size()-1); // // for (int i=0;i<external_rate_limiters_cow.size();i++){ // // Object[] entry = (Object[])external_rate_limiters_cow.get(i); // // if ( entry[0] != group ){ // // new_limiters.add( entry ); // } // } // // if ( new_limiters.size() == 0 ){ // // external_rate_limiters_cow = null; // // }else{ // // external_rate_limiters_cow = new_limiters; // } // } // // pm = peer_manager; // // }finally{ // // this_mon.exit(); // } // // if ( pm != null ){ // // pm.removeRateLimiter(group, upload); // } // } // // public void // enqueueReadRequest( // PEPeer peer, // DiskManagerReadRequest request, // DiskManagerReadRequestListener listener ) // { // getDiskManager().enqueueReadRequest( request, listener ); // } // // public boolean // activateRequest( // InetSocketAddress address ) // { // if ( getState() == DownloadManager.STATE_QUEUED ){ // // BloomFilter bloom = activation_bloom; // // if ( bloom == null ){ // // activation_bloom = bloom = BloomFilterFactory.createAddRemove4Bit( BLOOM_SIZE ); // } // // byte[] address_bytes = address.getAddress().getAddress(); // // int hit_count = bloom.add( address_bytes ); // // if ( hit_count > 5 ){ // // Logger.log( // new LogEvent( // this, // LogIDs.CORE, // LogEvent.LT_WARNING, // "Activate request for " + getDisplayName() + " from " + address + " denied as too many recently received" )); // // return( false ); // } // // Logger.log(new LogEvent(this, LogIDs.CORE, "Activate request for " + getDisplayName() + " from " + address )); // // long now = SystemTime.getCurrentTime(); // // // we don't really care about the bloom filter filling up and giving false positives // // as activation events should be fairly rare // // if ( now < activation_bloom_create_time || now - activation_bloom_create_time > ACTIVATION_REBUILD_TIME ){ // // activation_bloom = BloomFilterFactory.createAddRemove4Bit( BLOOM_SIZE ); // // activation_bloom_create_time = now; // } // // activation_count = bloom.getEntryCount(); // // activation_count_time = now; // // return( download_manager.activateRequest( activation_count )); // } // // return( false ); // } // // public void // deactivateRequest( // InetSocketAddress address ) // { // BloomFilter bloom = activation_bloom; // // if ( bloom != null ){ // // byte[] address_bytes = address.getAddress().getAddress(); // // int count = bloom.count( address_bytes); // // for (int i=0;i<count;i++){ // // bloom.remove( address_bytes ); // } // // activation_count = bloom.getEntryCount(); // } // } // // public int // getActivationCount() // { // // in the absence of any new activations we persist the last count for the activation rebuild // // period // // long now = SystemTime.getCurrentTime(); // // if ( now < activation_count_time ){ // // activation_count_time = now; // // }else if ( now - activation_count_time > ACTIVATION_REBUILD_TIME ){ // // activation_count = 0; // } // // return( activation_count ); // } // // public PeerManagerRegistration // getPeerManagerRegistration() // { // return( peer_manager_registration ); // } // // public boolean // isForceStart() // { // return( force_start ); // } // // public void // setForceStart( // boolean _force_start) // { // try{ // state_mon.enter(); // // if ( force_start != _force_start ){ // // force_start = _force_start; // // int state = getState(); // // if ( force_start && // ( state == DownloadManager.STATE_STOPPED || // state == DownloadManager.STATE_QUEUED )) { // // // Start it! (Which will cause a stateChanged to trigger) // // setState(DownloadManager.STATE_WAITING, false ); // } // } // }finally{ // // state_mon.exit(); // } // // // "state" includes the force-start setting // // download_manager.informStateChanged(); // } // // protected void // setFailed( // String reason ) // { // if ( reason != null ){ // // errorDetail = reason; // } // // stopIt( DownloadManager.STATE_ERROR, false, false ); // } // // // public boolean // filesExist( // boolean expected_to_be_allocated ) // { // if ( !expected_to_be_allocated ){ // // if ( !download_manager.isDataAlreadyAllocated()){ // // return( false ); // } // } // // DiskManager dm = getDiskManager(); // // if (dm != null) { // return dm.filesExist(); // } // // fileFacadeSet.makeSureFilesFacadeFilled(false); // // DiskManagerFileInfo[] files = fileFacadeSet.getFiles(); // // for (int i = 0; i < files.length; i++) { // DiskManagerFileInfo fileInfo = files[i]; // if (!fileInfo.isSkipped()) { // File file = fileInfo.getFile(true); // try { // if (!file.exists()) { // // // For multi-file torrents, complain if the save directory is missing. // if (!this.download_manager.getTorrent().isSimpleTorrent()) { // File save_path = this.download_manager.getAbsoluteSaveLocation(); // if (FileUtil.isAncestorOf(save_path, file) && !save_path.exists()) { // file = save_path; // We're going to abort very soon, so it's OK to overwrite this. // } // } // // setFailed(MessageText.getString("DownloadManager.error.datamissing") // + " " + file); // return false; // // } else if (fileInfo.getLength() < file.length()) { // // // file may be incremental creation - don't complain if too small // // // don't bitch if the user is happy with this // // if ( !COConfigurationManager.getBooleanParameter("File.truncate.if.too.large")){ // // setFailed(MessageText.getString("DownloadManager.error.badsize") // + " " + file + "(" + fileInfo.getLength() + "/" + file.length() + ")"); // // // return false; // } // } // } catch (Exception e) { // setFailed(e.getMessage()); // return false; // } // } // } // // return true; // } // // public DiskManagerFileInfoSet getDiskManagerFileInfoSet() // { // fileFacadeSet.makeSureFilesFacadeFilled(false); // // return fileFacadeSet; // } // // /** // * @deprecated use getDiskManagerFileInfoSet() instead // */ // public DiskManagerFileInfo[] // getDiskManagerFileInfo() // { // fileFacadeSet.makeSureFilesFacadeFilled(false); // // return( fileFacadeSet.getFiles() ); // } // // protected void // fileInfoChanged() // { // fileFacadeSet.makeSureFilesFacadeFilled(true); // } // // protected void // filePrioritiesChanged(List files) // { // if (!cached_values_set) { // fileFacadeSet.makeSureFilesFacadeFilled(false); // } // // // no need to calculate completeness if there are no DND files and the // // file being changed is not DND // if (!cached_has_dnd_files && files.size() == 1 && !((DiskManagerFileInfo)files.get(0)).isSkipped()){ // return; // } // // if it's more than one file just do the scan anyway // fileFacadeSet.makeSureFilesFacadeFilled(false); // calculateCompleteness( fileFacadeSet.facadeFiles ); // } // // protected void // calculateCompleteness( // DiskManagerFileInfo[] active ) // { // boolean complete_excluding_dnd = true; // // boolean has_dnd_files = false; // // for (int i = 0; i < active.length; i++) { // // DiskManagerFileInfo file = active[i]; // // if ( file.isSkipped()){ // // has_dnd_files = true; // // }else if (file.getDownloaded() != file.getLength()) { // // complete_excluding_dnd = false; // // } // // if(has_dnd_files && !complete_excluding_dnd) // break; // we can bail out early // } // // cached_complete_excluding_dnd = complete_excluding_dnd; // cached_has_dnd_files = has_dnd_files; // cached_values_set = true; // DownloadManagerState state = download_manager.getDownloadState(); // long flags = (cached_complete_excluding_dnd ? STATE_FLAG_COMPLETE_NO_DND : 0) | // (cached_has_dnd_files ? STATE_FLAG_HASDND : 0); // state.setLongParameter(DownloadManagerState.PARAM_DND_FLAGS, flags); // } // // /** // * Determine if the download is complete, excluding DND files. This // * function is mostly cached when there is a DiskManager. // * // * @return completion state // */ // protected boolean isDownloadComplete(boolean bIncludeDND) { // if (!cached_values_set) { // fileFacadeSet.makeSureFilesFacadeFilled(false); // } // // // The calculate from stats doesn't take into consideration DND // // So, if we have no DND files, use calculation from stats, which // // remembers things like whether the file was once complete // if (!cached_has_dnd_files) { // return stats.getDownloadCompleted(false) == 1000; // } // // // We have DND files. If we have an existing diskmanager, then it // // will have better information than the stats object. // DiskManager dm = getDiskManager(); // // //System.out.println(dm + ":" + (dm == null ? "null" : dm.getState() + ";" + dm.getRemainingExcludingDND())); // if (dm != null) { // // int dm_state = dm.getState(); // // if (dm_state == DiskManager.READY) { // long remaining = bIncludeDND ? dm.getRemaining() // : dm.getRemainingExcludingDND(); // return remaining == 0; // } // } // // // No DiskManager or it's in a bad state for us. // // Assumed: We have DND files // if (bIncludeDND) { // // Want to include DND files in calculation, which there some, which // // means completion MUST be false // return false; // } // // // Have DND files, bad DiskManager, and we don't want to include DND files // return cached_complete_excluding_dnd; // } // // protected PEPeerManager // getPeerManager() // { // return( peer_manager ); // } // // protected DiskManager // getDiskManager() // { // return( disk_manager_use_accessors ); // } // // protected String // getErrorDetail() // { // return( errorDetail ); // } // // protected void // setDiskManager( // DiskManager new_disk_manager, // DiskManagerListener new_disk_manager_listener ) // { // if ( new_disk_manager != null ){ // // new_disk_manager.setPieceCheckingEnabled( piece_checking_enabled ); // } // // try{ // disk_listeners_mon.enter(); // // DiskManager old_disk_manager = disk_manager_use_accessors; // // // remove any old listeners in case the diskmanager is still running async // // if ( old_disk_manager != null && disk_manager_listener_use_accessors != null ){ // // old_disk_manager.removeListener( disk_manager_listener_use_accessors ); // } // // disk_manager_use_accessors = new_disk_manager; // disk_manager_listener_use_accessors = new_disk_manager_listener; // // if ( new_disk_manager != null ){ // // new_disk_manager.addListener( new_disk_manager_listener ); // } // // // whether going from none->active or the other way, indicate that the file info // // has changed // // fileInfoChanged(); // // if ( new_disk_manager == null && old_disk_manager != null ){ // // disk_listeners.dispatch( LDT_DL_REMOVED, old_disk_manager ); // // }else if ( new_disk_manager != null && old_disk_manager == null ){ // // disk_listeners.dispatch( LDT_DL_ADDED, new_disk_manager ); // // }else{ // // Debug.out( "inconsistent DiskManager state - " + new_disk_manager + "/" + old_disk_manager ); // } // // }finally{ // // disk_listeners_mon.exit(); // } // } // // public void // addDiskListener( // DownloadManagerDiskListener listener ) // { // try{ // disk_listeners_mon.enter(); // // disk_listeners.addListener( listener ); // // DiskManager dm = getDiskManager(); // // if ( dm != null ){ // // disk_listeners.dispatch( listener, LDT_DL_ADDED, dm ); // } // }finally{ // // disk_listeners_mon.exit(); // } // } // // public void // removeDiskListener( // DownloadManagerDiskListener listener ) // { // try{ // disk_listeners_mon.enter(); // // disk_listeners.removeListener( listener ); // // }finally{ // // disk_listeners_mon.exit(); // } // } // // public long getDiskListenerCount() { // return disk_listeners.size(); // } // // public String // getDisplayName() // { // return( download_manager.getDisplayName()); // } // // public int // getUploadRateLimitBytesPerSecond() // { // return( download_manager.getEffectiveUploadRateLimitBytesPerSecond()); // } // // public int // getDownloadRateLimitBytesPerSecond() // { // return( stats.getDownloadRateLimitBytesPerSecond()); // } // // public int // getMaxUploads() // { // return( download_manager.getEffectiveMaxUploads()); // } // // public int // getMaxConnections() // { // int result; // // if ( download_manager.isMaxConnectionsWhenSeedingEnabled() && isStateSeeding()){ // // result = download_manager.getMaxConnectionsWhenSeeding(); // // }else{ // // result = download_manager.getMaxConnections(); // } // // return( result ); // } // // public int // getMaxSeedConnections() // { // return( download_manager.getMaxSeedConnections()); // } // // public boolean // isExtendedMessagingEnabled() // { // return( download_manager.isExtendedMessagingEnabled()); // } // // public boolean // isPeerExchangeEnabled() // { // return( download_manager.getDownloadState().isPeerSourceEnabled( PEPeerSource.PS_OTHER_PEER )); // } // // public int // getCryptoLevel() // { // return( download_manager.getCryptoLevel()); // } // // public boolean // isPeriodicRescanEnabled() // { // return( download_manager.getDownloadState().getFlag( DownloadManagerState.FLAG_SCAN_INCOMPLETE_PIECES )); // } // // public TRTrackerScraperResponse // getTrackerScrapeResponse() // { // return( download_manager.getTrackerScrapeResponse()); // } // // public String // getTrackerClientExtensions() // { // return( download_manager.getDownloadState().getTrackerClientExtensions()); // } // // public void // setTrackerRefreshDelayOverrides( // int percent ) // { // download_manager.setTrackerRefreshDelayOverrides( percent ); // } // // public boolean // isNATHealthy() // { // return( download_manager.getNATStatus() == ConnectionManager.NAT_OK ); // } // // public void // addPeer( // PEPeer peer ) // { // download_manager.addPeer( peer ); // } // // public void // removePeer( // PEPeer peer ) // { // download_manager.removePeer( peer ); // } // // public void // addPiece( // PEPiece piece ) // { // download_manager.addPiece( piece ); // } // // public void // removePiece( // PEPiece piece ) // { // download_manager.removePiece( piece ); // } // // public void // discarded( // PEPeer peer, // int bytes ) // { // if ( global_stats != null ){ // // global_stats.discarded( bytes ); // } // } // // public void // protocolBytesReceived( // PEPeer peer, // int bytes ) // { // if ( global_stats != null ){ // // global_stats.protocolBytesReceived( bytes, peer.isLANLocal()); // } // } // // public void // dataBytesReceived( // PEPeer peer, // int bytes ) // { // if ( global_stats != null ){ // // global_stats.dataBytesReceived( bytes, peer.isLANLocal()); // } // } // // public void // protocolBytesSent( // PEPeer peer, // int bytes ) // { // if ( global_stats != null ){ // // global_stats.protocolBytesSent( bytes, peer.isLANLocal()); // } // } // // public void // dataBytesSent( // PEPeer peer, // int bytes ) // { // if ( global_stats != null ){ // // global_stats.dataBytesSent( bytes, peer.isLANLocal()); // } // } // // public int getPosition() { // return download_manager.getPosition(); // } // // public void // addHTTPSeed( // String address, // int port ) // { // ExternalSeedPlugin plugin = getExternalSeedPlugin(); // // try{ // if ( plugin != null ){ // // Map config = new HashMap(); // // List urls = new ArrayList(); // // String seed_url = "http://" + UrlUtils.convertIPV6Host(address) + ":" + port + "/webseed"; // // urls.add( seed_url.getBytes()); // // config.put("httpseeds", urls); // // Map params = new HashMap(); // // params.put( "supports_503", new Long(0)); // params.put( "transient", new Long(1)); // // config.put("httpseeds-params", params); // // plugin.addSeed( org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl.getDownloadStatic( download_manager ), config); // } // }catch( Throwable e ){ // // Debug.printStackTrace(e); // } // } // // public void // priorityConnectionChanged( // boolean added ) // { // synchronized( this ){ // // if ( added ){ // // priority_connection_count++; // // }else{ // // priority_connection_count--; // } // } // } // // public boolean // hasPriorityConnection() // { // synchronized( this ){ // // return( priority_connection_count > 0 ); // } // } // // public String // getDescription() // { // return( download_manager.getDisplayName()); // } // // public LogRelation // getLogRelation() // { // return( this ); // } // // public String // getRelationText() // { // return( download_manager.getRelationText()); // } // // public Object[] // getQueryableInterfaces() // { // List interfaces = new ArrayList(); // // Object[] intf = download_manager.getQueryableInterfaces(); // // for (int i=0;i<intf.length;i++){ // // interfaces.add( intf[i] ); // } // // interfaces.add( download_manager ); // // DiskManager dm = getDiskManager(); // // if ( dm != null ){ // // interfaces.add( dm ); // } // // return( interfaces.toArray()); // } // // protected class FileInfoFacadeSet implements DiskManagerFileInfoSet { // // DiskManagerFileInfoSet delegate; // fileInfoFacade[] facadeFiles = new fileInfoFacade[0]; // default before torrent avail // // public DiskManagerFileInfo[] getFiles() { // return facadeFiles; // } // // public int nbFiles() { // if (delegate == null) { // return 0; // } // return delegate.nbFiles(); // } // // public void setPriority(boolean[] toChange, boolean setPriority) { // delegate.setPriority(toChange, setPriority); // } // // public void setSkipped(boolean[] toChange, boolean setSkipped) { // delegate.setSkipped(toChange, setSkipped); // } // // public boolean[] setStorageTypes(boolean[] toChange, int newStroageType) { // return delegate.setStorageTypes(toChange, newStroageType); // } // // /** XXX Don't call me, call makeSureFilesFacadeFilled() */ // protected void fixupFileInfo(fileInfoFacade[] info) { // // // too early in initialisation sequence to action this - it'll get reinvoked later anyway // if (info.length == 0) return; // // final List delayed_prio_changes = new ArrayList(0); // // try { // this_mon.enter(); // if (files_facade_destroyed) return; // // DiskManager dm = DownloadManagerController.this.getDiskManager(); // DiskManagerFileInfoSet active = null; // // if (dm != null) { // int dm_state = dm.getState(); // // grab the live file info if available // if (dm_state == DiskManager.CHECKING || dm_state == DiskManager.READY) // active = dm.getFileSet(); // // } // if (active == null) { // final boolean[] initialising = { true }; // // chance of recursion with this listener as the file-priority-changed is triggered // // synchronously during construction and this can cause a listener to reenter the // // incomplete fixup logic here + instantiate new skeletons..... // try { // skeleton_builds++; // if (skeleton_builds % 1000 == 0) { // Debug.outNoStack("Skeleton builds: " + skeleton_builds); // } // active = DiskManagerFactory.getFileInfoSkeleton(download_manager, new DiskManagerListener() { // public void stateChanged(int oldState, int newState) {} // // public void filePriorityChanged(DiskManagerFileInfo file) { // if (initialising[0]) { // delayed_prio_changes.add(file); // } else { // download_manager.informPriorityChange(file); // } // } // // public void pieceDoneChanged(DiskManagerPiece piece) {} // // public void fileAccessModeChanged(DiskManagerFileInfo file, int old_mode, int new_mode) {} // }); // } finally { // initialising[0] = false; // } // calculateCompleteness(active.getFiles()); // } // // DiskManagerFileInfo[] activeFiles = active.getFiles(); // // for (int i = 0; i < info.length; i++) // info[i].setDelegate(activeFiles[i]); // // delegate = active; // // } finally { // this_mon.exit(); // } // // fileFacadeSet.facadeFiles = info; // download_manager.informPrioritiesChange(delayed_prio_changes); // // delayed_prio_changes.clear(); // } // // private void makeSureFilesFacadeFilled(boolean refresh) { // if (!bInitialized) return; // too early // // if (facadeFiles.length == 0) { // fileInfoFacade[] newFacadeFiles = new fileInfoFacade[download_manager.getTorrent() == null // ? 0 : download_manager.getTorrent().getFiles().length]; // // for (int i = 0; i < newFacadeFiles.length; i++) // newFacadeFiles[i] = new fileInfoFacade(); // // // no need to set facadeFiles, it gets set to newFacadeFiles in fixup // fileFacadeSet.fixupFileInfo(newFacadeFiles); // } else if (refresh) { // fixupFileInfo(facadeFiles); // } // } // // // protected void destroyFileInfo() { // try { // this_mon.enter(); // if (fileFacadeSet == null || files_facade_destroyed) // return; // // files_facade_destroyed = true; // // for (int i = 0; i < facadeFiles.length; i++) // facadeFiles[i].close(); // } finally { // this_mon.exit(); // } // } // } // // protected class // fileInfoFacade // implements DiskManagerFileInfo // { // private DiskManagerFileInfo delegate; // // private List listeners; // // protected // fileInfoFacade() // { // } // // protected void // setDelegate( // DiskManagerFileInfo _delegate ) // { // if ( _delegate == delegate ){ // // return; // } // // if ( delegate != null ){ // // delegate.close(); // } // // delegate = _delegate; // // // transfer any existing listeners across // // if ( listeners != null ){ // // for (int i=0;i<listeners.size();i++){ // // delegate.addListener((DiskManagerFileInfoListener)listeners.get(i)); // } // } // } // // public void // setPriority( // boolean b ) // { // delegate.setPriority(b); // } // // public void // setSkipped( // boolean b) // { // delegate.setSkipped(b); // } // // // public boolean // setLink( // File link_destination ) // { // return( delegate.setLink( link_destination )); // } // // public boolean // setLinkAtomic( // File link_destination ) // { // return( delegate.setLinkAtomic( link_destination )); // } // // public File // getLink() // { // return( delegate.getLink()); // } // // public boolean // setStorageType( // int type ) // { // return( delegate.setStorageType( type )); // } // // public int // getStorageType() // { // return( delegate.getStorageType()); // } // // // public int // getAccessMode() // { // return( delegate.getAccessMode()); // } // // public long // getDownloaded() // { // return( delegate.getDownloaded()); // } // // public String // getExtension() // { // return( delegate.getExtension()); // } // // public int // getFirstPieceNumber() // { // return( delegate.getFirstPieceNumber()); // } // // public int // getLastPieceNumber() // { // return( delegate.getLastPieceNumber()); // } // // public long // getLength() // { // return( delegate.getLength()); // } // // public int // getNbPieces() // { // return( delegate.getNbPieces()); // } // // public boolean // isPriority() // { // return( delegate.isPriority()); // } // // public boolean // isSkipped() // { // return( delegate.isSkipped()); // } // // public int // getIndex() // { // return( delegate.getIndex()); // } // // public DiskManager // getDiskManager() // { // return( delegate.getDiskManager()); // } // // public DownloadManager // getDownloadManager() // { // return( download_manager ); // } // // public File // getFile( boolean follow_link ) // { // return( delegate.getFile( follow_link )); // } // // public TOTorrentFile // getTorrentFile() // { // return( delegate.getTorrentFile()); // } // // public void // flushCache() // // throws Exception // { // try{ // this_mon.enter(); // // delegate.flushCache(); // // }finally{ // // this_mon.exit(); // } // } // // public DirectByteBuffer // read( // long offset, // int length ) // // throws IOException // { // try{ // this_mon.enter(); // // return( delegate.read( offset, length )); // // }finally{ // // this_mon.exit(); // } // } // // public void // close() // { // try{ // this_mon.enter(); // // delegate.close(); // // }finally{ // // this_mon.exit(); // } // } // // public void // addListener( // DiskManagerFileInfoListener listener ) // { // if ( listeners == null ){ // // listeners = new ArrayList(); // } // // listeners.add( listener ); // // delegate.addListener( listener ); // } // // public void // removeListener( // DiskManagerFileInfoListener listener ) // { // listeners.remove( listener ); // // delegate.removeListener( listener ); // } // } // // public void generateEvidence(IndentWriter writer) { // writer.println("DownloadManager Controller:"); // // writer.indent(); // try { // writer.println("cached info: complete w/o DND=" // + cached_complete_excluding_dnd + "; hasDND? " + cached_has_dnd_files); // // writer.println("Complete w/DND? " + isDownloadComplete(true) // + "; w/o DND? " + isDownloadComplete(false)); // // writer.println("filesFacade length: " + fileFacadeSet.nbFiles()); // // if (force_start) { // writer.println("Force Start"); // } // // writer.println("FilesExist? " + filesExist(download_manager.isDataAlreadyAllocated())); // // } finally { // writer.exdent(); // } // } // // public class forceRecheckDiskManagerListener // implements DiskManagerListener // { // private final boolean wasForceStarted; // // private final int start_state; // // private final ForceRecheckListener l; // // public forceRecheckDiskManagerListener(boolean wasForceStarted, // int start_state, ForceRecheckListener l) { // this.wasForceStarted = wasForceStarted; // this.start_state = start_state; // this.l = l; // } // // public void stateChanged(int oldDMState, int newDMState) { // try { // this_mon.enter(); // // if (getDiskManager() == null) { // // // already closed down via stop // // download_manager.setAssumedComplete(false); // // if (l != null) { // l.forceRecheckComplete(download_manager); // } // // return; // } // } finally { // // this_mon.exit(); // } // // // if (newDMState == DiskManager.CHECKING) { // // fileFacadeSet.makeSureFilesFacadeFilled(true); // } // // if (newDMState == DiskManager.READY || newDMState == DiskManager.FAULTY) { // // force_start = wasForceStarted; // // stats.setDownloadCompleted(stats.getDownloadCompleted(true)); // // if (newDMState == DiskManager.READY) { // // try { // boolean only_seeding = false; // boolean update_only_seeding = false; // // try { // this_mon.enter(); // // DiskManager dm = getDiskManager(); // // if (dm != null) { // // dm.stop(false); // // only_seeding = dm.getRemainingExcludingDND() == 0; // // update_only_seeding = true; // // setDiskManager(null, null); // // if (start_state == DownloadManager.STATE_ERROR) { // // setState(DownloadManager.STATE_STOPPED, false); // // } else { // // setState(start_state, false); // } // } // } finally { // // this_mon.exit(); // // download_manager.informStateChanged(); // } // // // careful here, don't want to update seeding while holding monitor // // as potential deadlock // // if (update_only_seeding) { // // download_manager.setAssumedComplete(only_seeding); // } // // } catch (Exception e) { // // setFailed("Resume data save fails: " // + Debug.getNestedExceptionMessage(e)); // } // } else { // Faulty // // try { // this_mon.enter(); // // DiskManager dm = getDiskManager(); // // if (dm != null) { // // dm.stop(false); // // setDiskManager(null, null); // // setFailed(dm.getErrorMessage()); // } // } finally { // // this_mon.exit(); // } // // download_manager.setAssumedComplete(false); // // } // if (l != null) { // l.forceRecheckComplete(download_manager); // } // } // } // // public void filePriorityChanged(DiskManagerFileInfo file) { // download_manager.informPriorityChange(file); // } // // public void pieceDoneChanged(DiskManagerPiece piece) { // } // // public void fileAccessModeChanged(DiskManagerFileInfo file, int old_mode, // int new_mode) { // } // } //}