FileDocCategorySizeDatePackage
ExternalSeedPeer.javaAPI DocAzureus 3.0.3.413579Fri Aug 31 16:09:44 BST 2007com.aelitis.azureus.plugins.extseed

ExternalSeedPeer

public class ExternalSeedPeer extends Object implements ExternalSeedReaderListener, Peer

Fields Summary
private ExternalSeedPlugin
plugin
private org.gudy.azureus2.plugins.download.Download
download
private PeerManager
manager
private PeerStats
stats
private Map
user_data
private ExternalSeedReader
reader
private int
state
private byte[]
peer_id
private boolean[]
available
private boolean
availabilityAdded
private long
snubbed
private boolean
is_optimistic
private Monitor
connection_mon
private boolean
peer_added
private List
request_list
private List
listenerList
private Monitor
listenerListMon
private boolean
doing_allocations
Constructors Summary
protected ExternalSeedPeer(ExternalSeedPlugin _plugin, org.gudy.azureus2.plugins.download.Download _download, ExternalSeedReader _reader)

	
	
	
				
						
				 
	
		plugin		= _plugin;
		download	= _download;
		reader		= _reader;
				
		connection_mon	= plugin.getPluginInterface().getUtilities().getMonitor();
		
		Torrent	torrent = reader.getTorrent();
				
		available	= new boolean[(int)torrent.getPieceCount()];
		
		Arrays.fill( available, true );
		
		peer_id	= new byte[20];
		
		new Random().nextBytes( peer_id );
		
		peer_id[0]='E";
		peer_id[1]='x";
		peer_id[2]='t";
		peer_id[3]=' ";
		
		listenerList =new ArrayList();
		listenerListMon	= plugin.getPluginInterface().getUtilities().getMonitor();
		
		_reader.addListener( this );
	
Methods Summary
public voidaddListener(PeerListener listener)

		try{
			listenerListMon.enter();
						
			listenerList.add(listener);
			
		}finally{
			
			listenerListMon.exit();
		}
	
public voidaddListener(PeerListener2 listener)

		try{
			listenerListMon.enter();
						
			listenerList.add(listener);
			
		}finally{
			
			listenerListMon.exit();
		}
	
protected voidaddPeer()

		setState(Peer.HANDSHAKING);

		manager.addPeer( this );
		
			// we can get synchronously disconnected - e.g. IP filter rules
		
		if ( peer_added ){
			
			setState(Peer.TRANSFERING);
	
			try{
				listenerListMon.enter();
	
				if ( availabilityAdded ){
					
					Debug.out( "availabililty already added" );
					
				}else{
					
					availabilityAdded	= true;
	
					fireEvent( PeerEvent.ET_ADD_AVAILABILITY, getAvailable());				
				}
			
			}finally{
				
				listenerListMon.exit();
			}
		}
	
public booleanaddRequest(PeerReadRequest request)

		
		if ( !doing_allocations ){
			
			Debug.out( "request added when not in allocation phase" );
		}
		
		request_list.add( request );
		
		snubbed = 0;
		
		return( true );
	
public voidcancelRequest(PeerReadRequest request)

		reader.cancelRequest( request );
	
protected booleancheckConnection()

		boolean	state_changed = false;
		
		try{
			connection_mon.enter();
			
			boolean	active = reader.checkActivation( manager, this );
			
			if ( manager != null && active != peer_added ){
				
				state_changed	= true;
				
				boolean	peer_was_added	= peer_added;
				
				peer_added	= active;
				
				if ( active ){
					
					addPeer();
					
				}else{
										
					if ( peer_was_added ){
						
						removePeer();
					}
				}
			}
		}finally{
			
			connection_mon.exit();
		}
		
		return( state_changed );
	
public voidclose(java.lang.String reason, boolean closedOnError, boolean attemptReconnect)

		boolean	peer_was_added;
		
		try{
			connection_mon.enter();

			peer_was_added	= peer_added;

			reader.cancelAllRequests();
			
			reader.deactivate( reason );
			
			peer_added	= false;
			
			try{
				listenerListMon.enter();
				
				if ( availabilityAdded ){
								
					availabilityAdded	= false;
	
					fireEvent( PeerEvent.ET_REMOVE_AVAILABILITY, getAvailable());
				}
			}finally{
				
				listenerListMon.exit();
			}
		}finally{
			
			connection_mon.exit();
		}
		
		if ( peer_was_added ){
		
			manager.removePeer( this );
		}
		
		setState( Peer.DISCONNECTED );
		
		if ( reader.isTransient()){
							
			plugin.removePeer( this );
		}
	
protected voidfireEvent(int type, java.lang.Object data)

		try{
			listenerListMon.enter();

			for (int i =0; i <listenerList.size(); i++){
				
				try{
					Object	 _listener = listenerList.get(i);
						
					if ( _listener instanceof PeerListener ){
						
						PeerListener	listener = (PeerListener)_listener;
						
						if ( type == PeerEvent.ET_STATE_CHANGED ){
							
							listener.stateChanged(((Integer)data).intValue());
							
						}else if ( type == PeerEvent.ET_BAD_CHUNK ){
							
							Integer[]	d = (Integer[])data;
							
							listener.sentBadChunk(d[0].intValue(),d[1].intValue());
						}
					}else{
						
						PeerListener2	listener = (PeerListener2)_listener;
	
						listener.eventOccurred(
							new PeerEvent()
							{
								public int
								getType()
								{
									return( type );
								}
								
								public Object
								getData()
								{
									return( data );
								}
							});
					}
				}catch( Throwable e ){
					
					e.printStackTrace();
				}
			}
		}finally{
			
			listenerListMon.exit();
		}
	
public final boolean[]getAvailable()

		return( available );
	
public java.lang.StringgetClient()

		return( reader.getName());
	
public org.gudy.azureus2.plugins.network.ConnectiongetConnection()

		return( null );
	
protected org.gudy.azureus2.plugins.download.DownloadgetDownload()

		return( download );
	
public java.util.ListgetExpiredRequests()

		return( reader.getExpiredRequests());
		
	
public byte[]getHandshakeReservedBytes()

		return null;
	
public byte[]getId()

		return( peer_id );
	
public java.lang.StringgetIp()

		return( reader.getIP());
	
public PeerManagergetManager()

		return( manager );
	
public intgetMaximumNumberOfRequests()

		return( reader.getMaximumNumberOfRequests());
	
public java.lang.StringgetName()

		return( reader.getName());
	
public intgetNumberOfRequests()

		return( reader.getRequestCount() + request_list.size());
	
public intgetPercentDone()

		return( 1000 );
	
public intgetPercentDoneInThousandNotation()

		return( 1000 );
	
public intgetPercentDoneOfCurrentIncomingRequest()

		return( reader.getPercentDoneOfCurrentIncomingRequest());
	
public intgetPercentDoneOfCurrentOutgoingRequest()

		return( 0 );
	
public intgetPort()

		return( reader.getPort());
	
public int[]getPriorityOffsets()


		return( reader.getPriorityOffsets());
	
public java.util.MapgetProperties()

		return( new HashMap());
	
public java.util.ListgetRequests()

		return( reader.getRequests());
		
	
public longgetSnubbedTime()

		if ( !isSnubbed()){
			
			return 0;
		}
		
		final long now = plugin.getPluginInterface().getUtilities().getCurrentSystemTime();
		
		if ( now < snubbed ){
			
			snubbed = now - 26;	// odds are ...
		}
		
		return now - snubbed;
	
public intgetState()

		return state;
	
public PeerStatsgetStats()

		return( stats );
	
public org.gudy.azureus2.plugins.messaging.Message[]getSupportedMessages()

		return( new Message[0] );
	
public intgetTCPListenPort()

		return( 0 );
	
public intgetUDPListenPort()

		return( 0 );
	
public intgetUDPNonDataListenPort()

		return( 0 );
	
public java.lang.ObjectgetUserData(java.lang.Object key)

		if ( user_data == null ){
			
			return( null );
		}
		
		return( user_data.get( key ));
	
public booleanisChoked()

		return( false );
	
public booleanisChoking()

		return( false );
	
public booleanisDownloadPossible()

		return peer_added &&reader.isActive();
	
public booleanisIncoming()

		return( false );
	
public booleanisInterested()

		return( false );
	
public booleanisInteresting()

		return( true );
	
public booleanisOptimisticUnchoke()

		return( is_optimistic );
	
public final booleanisPieceAvailable(int pieceNumber)

		return( true );
	
public booleanisSeed()

		return( true );
	
public booleanisSnubbed()

		if ( snubbed != 0 ){
			
				// mindless snubbing control - if we have no outstanding requests then we
				// drop the snubbed status :)
			
			if ( reader.getRequestCount() == 0 ){
				
				snubbed = 0;
			}
		}
		
		return( snubbed != 0 );
	
public booleanisTransferAvailable()

		return( reader.isActive());
	
public intreadBytes(int max)

		int	res = reader.readBytes( max );
		
		if ( res > 0 ){
			
			stats.received( res );
		}
		
		return( res );
	
public voidremoveListener(PeerListener listener)

	
		try{
			listenerListMon.enter();
		
			listenerList.remove(listener);
		
		}finally{
			
			listenerListMon.exit();
		}
	
public voidremoveListener(PeerListener2 listener)

	
		try{
			listenerListMon.enter();
		
			listenerList.remove(listener);
		
		}finally{
			
			listenerListMon.exit();
		}
	
protected voidremovePeer()

	
		setState(Peer.CLOSING);
	
		try{
			listenerListMon.enter();
			
			if ( availabilityAdded ){
				
				availabilityAdded	= false;

				fireEvent( PeerEvent.ET_REMOVE_AVAILABILITY, getAvailable());				
			}
		}finally{
			
			listenerListMon.exit();
		}
				
		manager.removePeer( this );
		
		setState( Peer.DISCONNECTED );
	
public voidrequestAllocationComplete()

		reader.addRequests( request_list );
		
		request_list.clear();
		
		doing_allocations	= false;
	
public booleanrequestAllocationStarts(int[] base_priorities)

		if ( doing_allocations ){
			
			Debug.out( "recursive allocations" );
		}
		
		doing_allocations	= true;
		
		if ( request_list.size() != 0 ){
			
			Debug.out( "req list must be empty" );
		}
		
		PeerManager	pm = manager;
		
		if ( pm != null ){
		
			reader.calculatePriorityOffsets( pm, base_priorities );
		}
		
		return( true );
	
public voidrequestCancelled(PeerReadRequest request)

		PeerManager	man = manager;

		if ( man != null ){
			
			man.requestCancelled( request, this );
		}
	
public voidrequestComplete(PeerReadRequest request, PooledByteBuffer data)

		PeerManager	man = manager;
		
		if ( request.isCancelled() || man == null ){
	
			data.returnToPool();
			
		}else{
			
			try{
				man.requestComplete( request, data, this );
					
				// moved to the rate-limiting code for more accurate stats
				// stats.received( request.getLength());
				
			}catch( Throwable e ){
				
				data.returnToPool();
				
				e.printStackTrace();
			}
		}	
	
public voidrequestFailed(PeerReadRequest request)

		PeerManager	man = manager;

		if ( man != null ){
				
			man.requestCancelled( request, this );

			try{
				connection_mon.enter();
				
				if ( peer_added ){
					
					plugin.log( reader.getName() + " failed - " + reader.getStatus() + ", permanent = " + reader.isPermanentlyUnavailable());
						
					peer_added	= false;

					removePeer();
				}
			}finally{
				
				connection_mon.exit();
			}
			
			if ( reader.isTransient() && reader.isPermanentlyUnavailable()){
				
				plugin.removePeer( this );
			}
		}
	
protected booleansameAs(com.aelitis.azureus.plugins.extseed.ExternalSeedPeer other)

		return( reader.sameAs( other.reader ));
	
protected voidsetManager(PeerManager _manager)

		setState(Peer.CONNECTING);
		
		try{
			connection_mon.enter();

			manager	= _manager;
			
			if ( manager != null ){
				
				stats = manager.createPeerStats( this );
			}
			
			checkConnection();
			
		}finally{
			
			connection_mon.exit();
		}
	
public voidsetOptimisticUnchoke(boolean _is_optimistic)

		is_optimistic	= _is_optimistic;
	
public voidsetSnubbed(boolean b)

		if (!b){
			
			snubbed = 0;
			
		}else if ( snubbed == 0 ){
			
			snubbed = plugin.getPluginInterface().getUtilities().getCurrentSystemTime();
		}
	
protected voidsetState(int newState)

		state	= newState;
		
		fireEvent( PeerEvent.ET_STATE_CHANGED, new Integer( newState ));
	
public voidsetUserData(java.lang.Object key, java.lang.Object value)

		if ( user_data == null ){
			
			user_data	= new HashMap();
		}
		
		user_data.put( key, value );
	
public booleansupportsMessaging()

		return( false );
	
public intwriteBytes(int max)

		throw( new RuntimeException( "Not supported" ));