Package org.gudy.azureus2.pluginsimpl.local.peers

Source Code of org.gudy.azureus2.pluginsimpl.local.peers.PeerManagerImpl$CoreListener

/*
* File    : PeerManagerImpl.java
* Created : 28-Dec-2003
* 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.peers;

/**
* @author parg
*
*/

import java.util.*;

import org.gudy.azureus2.core3.disk.DiskManagerFileInfo;
import org.gudy.azureus2.core3.disk.DiskManagerListener;
import org.gudy.azureus2.core3.disk.DiskManagerPiece;
import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
import org.gudy.azureus2.core3.peer.*;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.TorrentUtils;
import org.gudy.azureus2.plugins.disk.DiskManager;
import org.gudy.azureus2.plugins.download.*;
import org.gudy.azureus2.plugins.peers.*;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.utils.PooledByteBuffer;
import org.gudy.azureus2.pluginsimpl.local.PluginCoreUtils;
import org.gudy.azureus2.pluginsimpl.local.disk.DiskManagerImpl;
import org.gudy.azureus2.pluginsimpl.local.download.DownloadManagerImpl;
import org.gudy.azureus2.pluginsimpl.local.utils.PooledByteBufferImpl;

import com.aelitis.azureus.core.networkmanager.NetworkManager;
import com.aelitis.azureus.core.peermanager.peerdb.PeerItem;

public class
PeerManagerImpl
  implements PeerManager
{
  private static final String  PEPEER_DATA_KEY  = PeerManagerImpl.class.getName();
 
  protected PEPeerManager  manager;
 
  protected static AEMonitor  pm_map_mon  = new AEMonitor( "PeerManager:Map" );

  public static PeerManagerImpl
  getPeerManager(
    PEPeerManager  _manager )
  {
    try{
      pm_map_mon.enter();
     
      PeerManagerImpl  res = (PeerManagerImpl)_manager.getData( "PluginPeerManager" );
     
      if ( res == null ){
       
        res = new PeerManagerImpl( _manager );
       
        _manager.setData( "PluginPeerManager", res );
      }
     
      return( res );
    }finally{
     
      pm_map_mon.exit();
    }
  }
 
  private Map    foreign_map    = new HashMap();
 
  private Map<PeerManagerListener,PEPeerManagerListener>  listener_map1   = new HashMap<PeerManagerListener,PEPeerManagerListener>();
  private Map<PeerManagerListener2,CoreListener>  listener_map2   = new HashMap<PeerManagerListener2,CoreListener>();
 
  protected AEMonitor  this_mon  = new AEMonitor( "PeerManager" );

  private final DiskManagerPiece[]  dm_pieces;
  private final PEPiece[]        pe_pieces;
  private pieceFacade[]        piece_facades;
 
  private boolean  destroyed;
 
  protected
  PeerManagerImpl(
    PEPeerManager  _manager )
  {
    manager  = _manager;
   
    dm_pieces  = _manager.getDiskManager().getPieces();
    pe_pieces  = _manager.getPieces();
   
    manager.addListener(
      new PEPeerManagerListener()
      {
         public void
         peerAdded(
          PEPeerManager  manager,
          PEPeer       peer )
         {
          
         }
        
         public void
         peerRemoved(
          PEPeerManager   manager,
          PEPeer       peer )
         {
           PeerImpl  dele = getPeerForPEPeer( peer );
          
           if ( dele != null ){
            
             dele.closed();
           }
         }
        
         public void
         peerDiscovered(
          PEPeerManager manager,
          PeerItem peer,
          PEPeer finder)
         {
         }
        
         public void
         peerSentBadData(
          PEPeerManager manager, PEPeer peer,  int pieceNumber)
         {
         }
        
         public void
         pieceAdded(
           PEPeerManager   manager,
           PEPiece     piece,
           PEPeer     for_peer )
         {
         }

         public void
         pieceRemoved(
           PEPeerManager   manager,
           PEPiece     piece )
         {
         }
         
         public void
         destroyed()
         { 
           synchronized( foreign_map ){

             destroyed  = true;

             Iterator it = foreign_map.values().iterator();

             while( it.hasNext()){

               try{
                 ((PeerForeignDelegate)it.next()).stop();

               }catch( Throwable e ){

                 Debug.printStackTrace( e );
               }
             }
           }
         }
      });
  }

  public PEPeerManager
  getDelegate()
  {
    return( manager );
  }

  public DiskManager
  getDiskManager()
  {
    return( new DiskManagerImpl( manager.getDiskManager()));
  }
 
  public PeerManagerStats
  getStats()
  {
    return(new PeerManagerStatsImpl( manager));
  }
 
  public boolean
  isSeeding()
  {
    // this is the wrong thing to check for seeding..
    return( manager.getDiskManager().getRemainingExcludingDND() == 0 ); //yuck
  }
 
  public boolean
  isSuperSeeding()
  {
    return( manager.isSuperSeedMode());
  }
 
  public Download
  getDownload()
 
    throws DownloadException
  {
    return( DownloadManagerImpl.getDownloadStatic( manager.getDiskManager().getTorrent()));
  }
 
  public Piece[]
  getPieces()
  {
    if ( piece_facades == null ){
     
      pieceFacade[]  pf = new pieceFacade[manager.getDiskManager().getNbPieces()];
     
      for (int i=0;i<pf.length;i++){
       
        pf[i] = new pieceFacade(i);
      }
     
      piece_facades  = pf;
    }
   
    return( piece_facades );
  }
 
  public PeerStats
  createPeerStats(
    Peer  peer )
  {
    PEPeer  delegate = mapForeignPeer( peer );
   
    return( new PeerStatsImpl( this, peer, manager.createPeerStats( delegate )));
  }
 
 
  public void
  requestComplete(
    PeerReadRequest    request,
    PooledByteBuffer   data,
    Peer         sender)
  {
    manager.writeBlock(
      request.getPieceNumber(),
      request.getOffset(),
      ((PooledByteBufferImpl)data).getBuffer(),
      mapForeignPeer( sender ),
            false);
   
    PeerForeignDelegate  delegate = lookupForeignPeer( sender );
   
    if ( delegate != null ){
     
      delegate.dataReceived();
    }
  }
 
  public void
  requestCancelled(
    PeerReadRequest    request,
    Peer        sender )
  {
    manager.requestCanceled((DiskManagerReadRequest)request );
  }

  protected int
  getPartitionID()
  {
    return( manager.getPartitionID());
  }
 
    // these are foreign peers
 
  public void
  addPeer(
    Peer    peer )
  {
      // no private check here, we come through here for webseeds for example
   
    manager.addPeer(mapForeignPeer( peer ));
  }
 
  public void
  removePeer(
    Peer    peer )
  {
    manager.removePeer(mapForeignPeer( peer ));
  }
 
  protected void
  removePeer(
    Peer    peer,
    String    reason )
  {
    manager.removePeer(mapForeignPeer( peer ), reason );
  }
 
  public void
  addPeer(
    String   ip_address,
    int   tcp_port )
  {
    addPeer(
      ip_address,
      tcp_port,
      0,
      NetworkManager.getCryptoRequired( NetworkManager.CRYPTO_OVERRIDE_NONE ));
  }
 
  public void
  addPeer(
    String     ip_address,
    int     tcp_port,
    boolean   use_crypto )
  {
    addPeer( ip_address, tcp_port, 0, use_crypto );
  }
 
  public void
  addPeer(
    String     ip_address,
    int     tcp_port,
    int      udp_port,
    boolean   use_crypto )
  {   
    addPeer( ip_address, tcp_port, udp_port, use_crypto, null );
  }

  public void
  addPeer(
    String     ip_address,
    int     tcp_port,
    int      udp_port,
    boolean   use_crypto,
    Map      user_data )
  {
    checkIfPrivate();
   
    if ( pluginPeerSourceEnabled()){

      manager.addPeer( ip_address, tcp_port, udp_port, use_crypto, user_data );
    }
  }
   
  protected boolean
  pluginPeerSourceEnabled()
  {
    if ( manager.isPeerSourceEnabled( PEPeerSource.PS_PLUGIN )){
     
      return( true );
     
    }else{
   
      Debug.out( "Plugin peer source disabled for " + manager.getDisplayName());
     
      return( false );
    }
  }
 
  protected void
  checkIfPrivate()
  {
    Download dl;
   
    try{
      dl = getDownload();
     
    }catch( Throwable e ){
     
      // if this didn't work then nothing much else will so just fall through
     
      return;
    }
   
    Torrent t = dl.getTorrent();
   
    if ( t != null ){
     
      if TorrentUtils.isReallyPrivate( PluginCoreUtils.unwrap( t ))){
       
        throw( new RuntimeException( "Torrent is private, peer addition not permitted" ));
      }
    }
  }
 
  public Peer[]
  getPeers()
  {
    List  l = manager.getPeers();
   
    Peer[]  res= new Peer[l.size()];
   
      // this is all a bit shagged as we should maintain the PEPeer -> Peer link rather
      // than continually creating new PeerImpls...
   
    for (int i=0;i<res.length;i++){
     
      res[i] = getPeerForPEPeer((PEPeer)l.get(i));
    }
   
    return( res );
  }
 
  public Peer[]
  getPeers(
    String    address )
  {
    List  l = manager.getPeers( address );
   
    Peer[]  res= new Peer[l.size()];
   
      // this is all a bit shagged as we should maintain the PEPeer -> Peer link rather
      // than continually creating new PeerImpls...
   
    for (int i=0;i<res.length;i++){
     
      res[i] = getPeerForPEPeer((PEPeer)l.get(i));
    }
   
    return( res );
  }
 

  public PeerDescriptor[]
    getPendingPeers()
    {
      return( manager.getPendingPeers());
    }
 
  public PeerDescriptor[]
  getPendingPeers(
    String    address )
  {
    return( manager.getPendingPeers( address ));
  }
 
  public long
  getTimeSinceConnectionEstablished(
    Peer    peer )
  {
    if ( peer instanceof PeerImpl ){
     
      return(((PeerImpl)peer).getDelegate().getTimeSinceConnectionEstablished());
    }else{
      PeerForeignDelegate  delegate = lookupForeignPeer( peer );
     
      if ( delegate != null ){
       
        return( delegate.getTimeSinceConnectionEstablished());
       
      }else{
       
        return( 0 );
      }
    }
  }
  public PEPeer
  mapForeignPeer(
    Peer  _foreign )
  {
    if ( _foreign instanceof PeerImpl ){
     
      return(((PeerImpl)_foreign).getDelegate());
    }
   
    synchronized( foreign_map ){
     
      PEPeer  local = (PEPeer)foreign_map.get( _foreign );
     
      if( local == null ){
       
        if ( destroyed ){
         
          Debug.out( "Peer added to destroyed peer manager" );
         
          return( null );
        }
       
        local   = new PeerForeignDelegate( this, _foreign );
       
        _foreign.setUserData( PeerManagerImpl.class, local );
       
        foreign_map.put( _foreign, local );
      }
     
      return( local );
    }
  }
 
  protected PeerForeignDelegate
  lookupForeignPeer(
    Peer  _foreign )
  {
    return((PeerForeignDelegate)_foreign.getUserData( PeerManagerImpl.class ));
  }
 
  public List
  mapForeignPeers(
    Peer[]  _foreigns )
  {
    List  res = new ArrayList();
   
    for (int i=0;i<_foreigns.length;i++){
   
      PEPeer  local = mapForeignPeer( _foreigns[i]);
     
        // could already be there if torrent contains two identical seeds (for whatever reason)
     
      if ( !res.contains( local )){
       
        res.add( local );
      }
    }
   
    return( res );
  }
 
  public static PeerImpl
  getPeerForPEPeer(
    PEPeer  pe_peer )
  {
    PeerImpl  peer = (PeerImpl)pe_peer.getData( PEPEER_DATA_KEY );
   
    if ( peer == null ){
     
      peer = new PeerImpl( pe_peer );
     
      pe_peer.setData( PEPEER_DATA_KEY, peer );
    }
   
    return( peer );
  }
 
  public int
  getUploadRateLimitBytesPerSecond()
  {
    return( manager.getUploadRateLimitBytesPerSecond());
  }

  public int
  getDownloadRateLimitBytesPerSecond()
  {
    return( manager.getDownloadRateLimitBytesPerSecond());
  }
 
  public void
  addListener(
    final PeerManagerListener  l )
  {
    try{
      this_mon.enter();

      final Map  peer_map = new HashMap();

      PEPeerManagerListener core_listener = new PEPeerManagerListener() {
        public void peerAdded( PEPeerManager manager, PEPeer peer ) {
          PeerImpl pi = getPeerForPEPeer( peer );
          peer_map.put( peer, pi );
          l.peerAdded( PeerManagerImpl.this, pi );
        }

        public void peerRemoved( PEPeerManager manager, PEPeer peer ) {
          PeerImpl  pi = (PeerImpl)peer_map.remove( peer );

          if ( pi == null ){
            // somewhat inconsistently we get told here about the removal of
            // peers that never connected (and weren't added)
            // Debug.out( "PeerManager: peer not found");
          }
          else{        
            l.peerRemoved( PeerManagerImpl.this, pi );
          }
        }
       
        public void
        peerDiscovered(
          PEPeerManager manager,
          PeerItem peer,
          PEPeer finder)
        {
        }
       
        public void
        pieceAdded(
          PEPeerManager   manager,
          PEPiece     piece,
          PEPeer       for_peer )
        {
        }
         
        public void
        pieceRemoved(
          PEPeerManager   manager,
          PEPiece     piece )
        {
        }
       
        public void
        peerSentBadData(PEPeerManager manager, PEPeer peer,  int pieceNumber)
        {
        }
       
        public void
        destroyed()
        {
        }
      };

      listener_map1.put( l, core_listener );

      manager.addListener( core_listener );
    }finally{

      this_mon.exit();
    }
  }
 
  public void
  removeListener(
    PeerManagerListener  l )
  {
    try{
      this_mon.enter();
   
      PEPeerManagerListener core_listener  = (PEPeerManagerListener)listener_map1.remove( l );
   
      if ( core_listener != null ){
       
        manager.removeListener( core_listener );
      }
     
    }finally{
      this_mon.exit();
    }
  }
 
  public void
  addListener(
    final PeerManagerListener2  l )
  {
    try{
      this_mon.enter();

      CoreListener core_listener = new CoreListener( l );
     
      listener_map2.put( l, core_listener );

      manager.addListener( core_listener );
     
      manager.getDiskManager().addListener( core_listener );
    }finally{

      this_mon.exit();
    }
  }
 
  public void
  removeListener(
    PeerManagerListener2  l )
  {
    try{
      this_mon.enter();
   
      CoreListener core_listener  = listener_map2.remove( l );
   
      if ( core_listener != null ){
       
        manager.removeListener( core_listener );
       
        manager.getDiskManager().removeListener( core_listener );
      }
     
    }finally{
     
      this_mon.exit();
    }
  }
 
  protected class
  pieceFacade
    implements Piece
  {
    private final int  index;
   
    protected
    pieceFacade(
      int    _index )
    {
      index  = _index;
    }
   
    public int
    getIndex()
    {
      return( index );
    }
   
    public int
    getLength()
    {
      return( dm_pieces[index].getLength());
    }
   
    public boolean
    isDone()
    {
      return( dm_pieces[index].isDone());
    }
   
    public boolean
    isNeeded()
    {
      return( dm_pieces[index].isNeeded());
    }
   
    public boolean
    isDownloading()
    {
      return( pe_pieces[index] != null );
    }
   
    public boolean
    isFullyAllocatable()
    {
      if ( pe_pieces[index] != null ){
       
        return( false );
      }
     
      return( dm_pieces[index].isInteresting());
    }
   
    public int
    getAllocatableRequestCount()
    {
      PEPiece  pe_piece = pe_pieces[index];
     
      if ( pe_piece != null ){
       
        return( pe_piece.getNbUnrequested());
      }
     
      if ( dm_pieces[index].isInteresting() ){
       
        return( dm_pieces[index].getNbBlocks());
      }
     
      return( 0 );
    }
   
    public Peer
    getReservedFor()
    {
      PEPiece piece = pe_pieces[index];

      if ( piece != null ){
             
        String ip = piece.getReservedBy();
       
        if ( ip != null ){
         
          List<PEPeer> peers = manager.getPeers( ip );
         
          if ( peers.size() > 0 ){
           
            return( getPeerForPEPeer( peers.get(0)));
          }
        }
      }
     
      return( null );
    }
   
    public void
    setReservedFor(
      Peer  peer )
    {
      PEPiece piece = pe_pieces[index];
     
      PEPeer mapped_peer = mapForeignPeer( peer );
     
      if ( piece != null && mapped_peer != null ){
       
        piece.setReservedBy( peer.getIp());
     
        mapped_peer.addReservedPieceNumber( index );
      }
    }
  }
 
  private class
  CoreListener
    implements PEPeerManagerListener, DiskManagerListener
  {
    private PeerManagerListener2    listener;
    private Map<PEPeer, Peer>      peer_map = new HashMap<PEPeer, Peer>();

    private
    CoreListener(
      PeerManagerListener2    _listener )
    {
      listener  = _listener;
    }
   
    public void
    peerAdded(
      PEPeerManager manager, PEPeer peer )
    {
      PeerImpl pi = getPeerForPEPeer( peer );
     
      peer_map.put( peer, pi );
     
      fireEvent(
        PeerManagerEvent.ET_PEER_ADDED,
        pi,
        null,
        null );
    }
 
    public void
    peerRemoved(
      PEPeerManager manager,
      PEPeer peer )
    {
      PeerImpl  pi = (PeerImpl)peer_map.remove( peer );
 
      if ( pi == null ){
 
      }else{
       
        fireEvent(
          PeerManagerEvent.ET_PEER_REMOVED,
          pi,
          null,
          null );
      }
    }
   
    public void
    peerDiscovered(
      PEPeerManager   manager,
      PeerItem     peer_item,
      PEPeer       finder )
    {
      PeerImpl  pi;
     
      if ( finder != null ){
       
        pi = getPeerForPEPeer( finder );
       
        peer_map.put( finder, pi );
       
      }else{
       
        pi = null;
      }
     
      fireEvent(
        PeerManagerEvent.ET_PEER_DISCOVERED,
        pi,
        peer_item,
        null );
    }
   
    public void
    pieceAdded(
      PEPeerManager   manager,
      PEPiece     piece,
      PEPeer       for_peer )
    {
      PeerImpl pi = for_peer==null?null:getPeerForPEPeer( for_peer );
 
      fireEvent(
          PeerManagerEvent.ET_PIECE_ACTIVATED,
          pi,
          null,
          new pieceFacade( piece.getPieceNumber()));
    }
     
    public void
    pieceRemoved(
      PEPeerManager   manager,
      PEPiece     piece )
    {
      fireEvent(
          PeerManagerEvent.ET_PIECE_DEACTIVATED,
          null,
          null,
          new pieceFacade( piece.getPieceNumber()));
    }
   
    public void
    peerSentBadData(
      PEPeerManager   manager,
      PEPeer       peer,
      int       pieceNumber)
    {
      PeerImpl pi = getPeerForPEPeer( peer );
     
      peer_map.put( peer, pi );
     
      fireEvent(
        PeerManagerEvent.ET_PEER_SENT_BAD_DATA,
        pi,
        null,
        new Integer( pieceNumber ));
     
    }
   
      // disk manager methods
   
    public void
    stateChanged(
      int oldState,
      int  newState )
    {
    }
   
    public void
    filePriorityChanged(
      DiskManagerFileInfo    file )
    {
    }

    public void
    pieceDoneChanged(
      DiskManagerPiece    piece )
    {
      fireEvent(
          PeerManagerEvent.ET_PIECE_COMPLETION_CHANGED,
          null,
          null,
          new pieceFacade( piece.getPieceNumber()));
    }
   
    public void
    fileAccessModeChanged(
      DiskManagerFileInfo    file,
      int            old_mode,
      int            new_mode )
    {
    }
   
    protected void
    fireEvent(
      final int      type,
      final Peer      peer,
      final PeerItem    peer_item,
      final Object    data )
    {
      listener.eventOccurred(
        new PeerManagerEvent()
        {
          public PeerManager
          getPeerManager()
          {
            return( PeerManagerImpl.this );
          }
         
          public int
          getType()
          {
            return( type );
          }
         
          public Peer
          getPeer()
          {
            return( peer );
          }
         
          public PeerDescriptor
          getPeerDescriptor()
          {
            return( peer_item );
          }
         
          public Object
          getData()
          {
            return( data );
          }
        });
    }
     
     
    public void
    destroyed()
    {
    }
  }
}
TOP

Related Classes of org.gudy.azureus2.pluginsimpl.local.peers.PeerManagerImpl$CoreListener

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