⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 globalmanagerimpl.java

📁 基于JXTA开发平台的下载软件开发源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/*
 * File    : GlobalManagerImpl.java
 * Created : 21-Oct-2003
 * By      : stuff
 * 
 * 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.core3.global.impl;

/*
 * Created on 30 juin 2003
 *
 */

import java.io.*;
import java.net.NetworkInterface;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Comparator;
import java.util.Collections;
import java.util.Set;

import com.aelitis.azureus.core.AzureusCoreListener;

import org.gudy.azureus2.core3.global.*;
import org.gudy.azureus2.core3.config.*;
import org.gudy.azureus2.core3.disk.DiskManager;
import org.gudy.azureus2.core3.download.*;
import org.gudy.azureus2.core3.internat.MessageText;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.peer.PEPeerManager;
import org.gudy.azureus2.core3.tracker.client.*;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.core3.category.CategoryManager;
import org.gudy.azureus2.core3.category.Category;
import org.gudy.azureus2.plugins.network.ConnectionManager;

import com.aelitis.azureus.core.helpers.TorrentFolderWatcher;


/**
 * @author Olivier
 * 
 */
public class GlobalManagerImpl 
	implements 	GlobalManager, DownloadManagerListener, AEDiagnosticsEvidenceGenerator
{
	private static final LogIDs LOGID = LogIDs.CORE;
	
		// GlobalManagerListener support
		// Must be an async listener to support the non-synchronised invocation of
		// listeners when a new listener is added and existing downloads need to be
		// reported
	
	private static final int LDT_MANAGER_ADDED			= 1;
	private static final int LDT_MANAGER_REMOVED		= 2;
	private static final int LDT_DESTROY_INITIATED		= 3;
	private static final int LDT_DESTROYED				= 4;
    private static final int LDT_SEEDING_ONLY           = 5;
	
	private ListenerManager	listeners 	= ListenerManager.createAsyncManager(
		"GM:ListenDispatcher",
		new ListenerManagerDispatcher()
		{
			public void
			dispatch(
				Object		_listener,
				int			type,
				Object		value )
			{
				GlobalManagerListener	target = (GlobalManagerListener)_listener;
		
				if ( type == LDT_MANAGER_ADDED ){
					
					target.downloadManagerAdded((DownloadManager)value);
					
				}else if ( type == LDT_MANAGER_REMOVED ){
					
					target.downloadManagerRemoved((DownloadManager)value);
					
				}else if ( type == LDT_DESTROY_INITIATED ){
					
					target.destroyInitiated();
					
				}else if ( type == LDT_DESTROYED ){
					
					target.destroyed();
                    
				}else if ( type == LDT_SEEDING_ONLY ){
                    
                    target.seedingStatusChanged( ((Boolean)value).booleanValue() );
                }
			}
		});
	
		// GlobalManagerDownloadWillBeRemovedListener support
		// Not async (doesn't need to be and can't be anyway coz it has an exception)
	
	private static final int LDT_MANAGER_WBR			= 1;
	
	private ListenerManager	removal_listeners 	= ListenerManager.createManager(
			"GM:DLWBRMListenDispatcher",
			new ListenerManagerDispatcherWithException()
			{
				public void
				dispatchWithException(
					Object		_listener,
					int			type,
					Object		value )
				
					throws GlobalManagerDownloadRemovalVetoException
				{					
					GlobalManagerDownloadWillBeRemovedListener	target = (GlobalManagerDownloadWillBeRemovedListener)_listener;
					
					target.downloadWillBeRemoved((DownloadManager)value);
				}
			});
	
	private List 		managers_cow	= new ArrayList();
	private AEMonitor	managers_mon	= new AEMonitor( "GM:Managers" );
	
	private Map		manager_map			= new HashMap();
		
	private Checker checker;
	private GlobalManagerStatsImpl		stats;
    private long last_swarm_stats_calc_time		= 0;
    private long last_swarm_stats				= 0;
	    

	private TRTrackerScraper 			trackerScraper;
	private GlobalManagerStatsWriter 	stats_writer;
	private GlobalManagerHostSupport	host_support;
  
	private Map							saved_download_manager_state	= new HashMap();
	
	private TorrentFolderWatcher torrent_folder_watcher;
  
	private ArrayList paused_list = new ArrayList();
	private final AEMonitor paused_list_mon = new AEMonitor( "GlobalManager:PL" );
  
  
  
	/* Whether the GlobalManager is active (false) or stopped (true) */
  
	private volatile boolean 	isStopping;
	private volatile boolean	destroyed;
	private volatile boolean 	needsSaving = false;
  
	private boolean seeding_only_mode = false;
  
	private int 	nat_status				= ConnectionManager.NAT_UNKNOWN;
	private boolean	nat_status_probably_ok;
	
	private Set		old_network_interfaces;
	private long	last_network_change;
	
	public class Checker extends AEThread {
    int loopFactor;
    private static final int waitTime = 10*1000;
    // 5 minutes save resume data interval (default)
    private int saveResumeLoopCount = 5*60*1000 / waitTime;
    private int netCheckLoopCount	= 60*1000 / waitTime;
    private int natCheckLoopCount	= 30*1000 / waitTime;
       
    private AESemaphore	run_sem = new AESemaphore( "GM:Checker:run");
    

     public Checker() {
      super("Global Status Checker");
      loopFactor = 0;
      setPriority(Thread.MIN_PRIORITY);
      //determineSaveResumeDataInterval();
    }

    private void determineSaveResumeDataInterval() {
      int saveResumeInterval = COConfigurationManager.getIntParameter("Save Resume Interval", 5);
      if (saveResumeInterval >= 1 && saveResumeInterval <= 90)
        saveResumeLoopCount = saveResumeInterval * 60000 / waitTime;
    }

    public void 
	runSupport() 
    {
      while ( true ){

      	try{
	        loopFactor++;
	        
	        determineSaveResumeDataInterval();
	        
	        if ((loopFactor % saveResumeLoopCount == 0) || needsSaving) {
	          	
	        	saveDownloads( true );
	        }
	        
	        if ((loopFactor % netCheckLoopCount == 0)) {
          	
	        	checkNetwork();
	        }
	        
	        if ((loopFactor % natCheckLoopCount == 0)) {
	          	
	        	computeNATStatus();
	        	
	        		// we need this periodic check to pick up on DND file state changes (someone changes
	        		// a file from DND to normal and consequentially changes to a non-seeding mode). 
	        		// Doing this via listeners is too much effort
	        	
		        checkSeedingOnlyState();
	        }
	        	
	        for (Iterator it=managers_cow.iterator();it.hasNext();) {
          	
	        	DownloadManager manager = (DownloadManager)it.next();
            
	        	if ( loopFactor % saveResumeLoopCount == 0 ) {
	        		
	        		manager.saveResumeData();
	        	}
	        	
		            /*
		             * seeding rules have been moved to StartStopRulesDefaultPlugin
		             */
	              
	         		// Handle forced starts here
         	
	        	if (	manager.getState() == DownloadManager.STATE_READY &&
	        			manager.isForceStart()) {
            	
	        		manager.startDownload();
	           }
	        }

      	}catch( Throwable e ){
      		
      		Debug.printStackTrace( e );
      	}
      	
        try {
        	run_sem.reserve(waitTime);
        	
        	if ( run_sem.isReleasedForever()){
        		
        		break;
        	}
        }
        catch (Exception e) {
        	Debug.printStackTrace( e );
        }
      }
    }

    public void stopIt() {
      run_sem.releaseForever();
    }
  }

  public 
  GlobalManagerImpl(
  		AzureusCoreListener listener)
  {
    //Debug.dumpThreadsLoop("Active threads");
  	
  	AEDiagnostics.addEvidenceGenerator( this );
	
    stats = new GlobalManagerStatsImpl( this );
       
    try{
    	stats_writer = new GlobalManagerStatsWriter( this );
    	
    }catch( Throwable e ){
    	
    	Logger.log(new LogEvent(LOGID, "Stats unavailable", e ));
    }
           
    if (listener != null)
      listener.reportCurrentTask(MessageText.getString("splash.initializeGM") + ": " +
                            MessageText.getString("splash.loadingTorrents"));
    loadDownloads(listener);
    if (listener != null)
      listener.reportCurrentTask(MessageText.getString("splash.initializeGM"));

    // Initialize scraper after loadDownloads so that we can merge scrapes
    // into one request per tracker
    trackerScraper = TRTrackerScraperFactory.getSingleton();
    
    trackerScraper.setClientResolver(
    	new TRTrackerScraperClientResolver()
		{
    		public int
			getStatus(
				byte[]	torrent_hash )
    		{
       			DownloadManager	dm = getDownloadManager(torrent_hash);
    			
    			if ( dm == null ){

    				return( TRTrackerScraperClientResolver.ST_NOT_FOUND );
    			}
    			    			
    			int	dm_state = dm.getState();
    			
    			if ( 	dm_state == DownloadManager.STATE_QUEUED ){
    				
    				return( TRTrackerScraperClientResolver.ST_QUEUED );
    				
    			}else if ( 	dm_state == DownloadManager.STATE_DOWNLOADING ||
    						dm_state == DownloadManager.STATE_SEEDING ){
    				
    				return( TRTrackerScraperClientResolver.ST_RUNNING );
    			}
    			
    			return( TRTrackerScraperClientResolver.ST_OTHER );
    		}
    		
    		public boolean
			isNetworkEnabled(
				byte[]	hash,
				URL		url )
    		{
       			DownloadManager	dm = getDownloadManager(hash);
    			
    			if ( dm == null ){
    				
    				return( false );
    			}
    			
    			String	nw = AENetworkClassifier.categoriseAddress( url.getHost());
    			
    			String[]	networks = dm.getDownloadState().getNetworks();
    			
    			for (int i=0;i<networks.length;i++){
    				
    				if ( networks[i] ==  nw ){
    					
    					return( true );
    				}
    			}
    			
    			return( false );
    		}
    		
    		public String
    		getExtensions(
    			byte[]	hash )
    		{
     			DownloadManager	dm = getDownloadManager(hash);
    			
    			if ( dm == null ){
    				
    				return( "" );
    			} 	
    			
    			return( dm.getDownloadState().getTrackerClientExtensions());
    		}
		});
    
    trackerScraper.addListener(
    	new TRTrackerScraperListener() {
    		public void scrapeReceived(TRTrackerScraperResponse response) {
    			byte[]	hash = response.getHash();
    			
    			if ( response.isValid() ){
    				DownloadManager manager = (DownloadManager)manager_map.get(new HashWrapper(hash));
    				if ( manager != null ) {
    					manager.setTrackerScrapeResponse( response );
    				}
    			}
    		}
    	});
    
    try{  
	    host_support = new GlobalManagerHostSupport( this ); 

    }catch( Throwable e ){
    	
    	Logger.log(new LogEvent(LOGID, "Hosting unavailable", e));
    }
    
    checker = new Checker();   
       	
    checker.start();
    
    if ( stats_writer != null ){
    	
    	stats_writer.initialisationComplete();
    }
    
    torrent_folder_watcher = new TorrentFolderWatcher( this );
  }

  public DownloadManager 
  addDownloadManager(
  		String fileName, 
		String savePath) 
  {
  	return addDownloadManager(fileName, savePath, DownloadManager.STATE_WAITING, true);
  }
   
	public DownloadManager
	addDownloadManager(
	    String 		fileName,
	    String 		savePath,
	    int         initialState,
		boolean		persistent )
	{
	 	return( addDownloadManager(fileName, savePath, initialState, persistent, false ));
	}
	
  /**
   * @return true, if the download was added
   *
   * @author Rene Leonhardt
   */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -