Package com.aelitis.azureus.plugins.net.buddy

Source Code of com.aelitis.azureus.plugins.net.buddy.BuddyPluginAZ2$chatMessage

/*
* Created on Apr 10, 2008
* Created by Paul Gardner
*
* Copyright 2008 Vuze, Inc.  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; version 2 of the License only.
*
* 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.
*/


package com.aelitis.azureus.plugins.net.buddy;

import java.security.SecureRandom;
import java.util.*;

import org.gudy.azureus2.core3.util.AEThread2;
import org.gudy.azureus2.core3.util.Base32;
import org.gudy.azureus2.core3.util.Debug;
import org.gudy.azureus2.core3.util.RandomUtils;
import org.gudy.azureus2.plugins.PluginInterface;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.plugins.ui.UIManagerEvent;

import com.aelitis.azureus.core.util.CopyOnWriteList;

public class
BuddyPluginAZ2
{
  public static final int RT_AZ2_REQUEST_MESSAGE    = 1;
  public static final int RT_AZ2_REPLY_MESSAGE    = 2;
 
  public static final int RT_AZ2_REQUEST_SEND_TORRENT  = 3;
  public static final int RT_AZ2_REPLY_SEND_TORRENT  = 4;

  public static final int RT_AZ2_REQUEST_CHAT      = 5;
  public static final int RT_AZ2_REPLY_CHAT      = 6;

  public static final int RT_AZ2_REQUEST_TRACK    = 7;
  public static final int RT_AZ2_REPLY_TRACK      = 8;

  public static final int RT_AZ2_REQUEST_RSS      = 9;
  public static final int RT_AZ2_REPLY_RSS      = 10;

  public static final int CHAT_MSG_TYPE_TEXT            = 1;
  public static final int CHAT_MSG_TYPE_PARTICIPANTS_ADDED    = 2;
  public static final int CHAT_MSG_TYPE_PARTICIPANTS_REMOVED    = 3;
 

  private static final int SEND_TIMEOUT = 2*60*1000;
 
  private BuddyPlugin    plugin;
 
  private Map        chats     = new HashMap();
 
  private CopyOnWriteList  listeners = new CopyOnWriteList();
 
  private CopyOnWriteList  track_listeners = new CopyOnWriteList();
 
  protected
  BuddyPluginAZ2(
    BuddyPlugin    _plugin )
  {
    plugin  = _plugin;
   
    plugin.addRequestListener(
        new BuddyPluginBuddyRequestListener()
        {
          public Map
          requestReceived(
            BuddyPluginBuddy  from_buddy,
            int          subsystem,
            Map          request )
         
            throws BuddyPluginException
          {
            if ( subsystem == BuddyPlugin.SUBSYSTEM_AZ2 ){
             
              if ( !from_buddy.isAuthorised()){
             
                throw( new BuddyPluginException( "Unauthorised" ));
              }
           
              return( processAZ2Request( from_buddy, request ));
            }

            return( null );
          }
         
          public void
          pendingMessages(
            BuddyPluginBuddy[]  from_buddies )
          {
          }
        });
  }
 
  protected Map
  processAZ2Request(
    final BuddyPluginBuddy  from_buddy,
    Map            request )   
   
    throws BuddyPluginException
  {
    logMessage( "AZ2 request received: " + from_buddy.getString() + " -> " + request );
     
    int  type = ((Long)request.get( "type" )).intValue();
   
    Map  reply = new HashMap();
       
    if ( type == RT_AZ2_REQUEST_MESSAGE ){
     
      try{
        String  msg = new String( (byte[])request.get( "msg" ), "UTF8" );
     
        from_buddy.setLastMessageReceived( msg );
       
      }catch( Throwable e ){
       
      }
     
      reply.put( "type", new Long( RT_AZ2_REPLY_MESSAGE ));

    }else if type == RT_AZ2_REQUEST_SEND_TORRENT ){
     
      try{
        final Torrent  torrent = plugin.getPluginInterface().getTorrentManager().createFromBEncodedData((byte[])request.get( "torrent" ));
     
        new AEThread2( "torrentAdder", true )
        {
          public void
          run()
          {
            PluginInterface pi = plugin.getPluginInterface();
           
            String msg = pi.getUtilities().getLocaleUtilities().getLocalisedMessageText(
                "azbuddy.addtorrent.msg",
                new String[]{ from_buddy.getName(), torrent.getName() });
           
            long res = pi.getUIManager().showMessageBox(
                    "azbuddy.addtorrent.title",
                    "!" + msg + "!",
                    UIManagerEvent.MT_YES | UIManagerEvent.MT_NO );
           
            if ( res == UIManagerEvent.MT_YES ){
           
              pi.getUIManager().openTorrent( torrent );
            }
          }
        }.start();
       
        reply.put( "type", new Long( RT_AZ2_REPLY_SEND_TORRENT ));
       
      }catch( Throwable e ){
       
        throw( new BuddyPluginException( "Torrent receive failed " + type ));
      }
    }else if type == RT_AZ2_REQUEST_CHAT ){
     
      Map msg = (Map)request.get( "msg" );
     
      String  id = new String((byte[])msg.get( "id" ));
     
      chatInstance  chat;
      boolean      new_chat = false;
     
      synchronized( chats ){
       
         chat = (chatInstance)chats.get( id );
        
         if ( chat == null ){
          
           if ( chats.size() > 32 ){
            
             throw( new BuddyPluginException( "Too many chats" ));
           }
          
           chat = new chatInstance( id );
          
           chats.put( id, chat );
          
           new_chat = true;
         }
      }
     
      if ( new_chat ){
     
        informCreated( chat );
      }
     
      chat.addParticipant( from_buddy );
     
      chat.process( from_buddy, msg );
           
      reply.put( "type", new Long( RT_AZ2_REPLY_CHAT ));
           
    }else if type == RT_AZ2_REQUEST_TRACK ){
     
      Map msg = (Map)request.get( "msg" );

      Iterator it = track_listeners.iterator();
     
      boolean  ok = false;
     
      while( it.hasNext()){
       
        try{
     
          Map res = ((BuddyPluginAZ2TrackerListener)it.next()).messageReceived( from_buddy, msg );
         
          if ( res != null ){
           
            reply.put( "msg", res );
            reply.put( "type", new Long( RT_AZ2_REPLY_TRACK ));

            ok = true;
           
            break;
          }
        }catch( Throwable e ){
         
          Debug.printStackTrace(e);
        }
      }
     
      if ( !ok ){
     
        throw( new BuddyPluginException( "Unhandled request type " + type ));
      }
    }else if type == RT_AZ2_REQUEST_RSS ){
       
      try{
        Map<String,Object> res = new HashMap<String, Object>();

        reply.put( "msg", res );
        reply.put( "type", new Long( RT_AZ2_REPLY_RSS ));

        Map msg = (Map)request.get( "msg" );

        String category = new String((byte[])msg.get( "cat"), "UTF-8" );
       
        byte[] hash  = (byte[])msg.get( "hash" );
       
        if ( hash == null ){
         
          byte[]  if_mod   = (byte[])msg.get( "if_mod" );
         
          BuddyPlugin.feedDetails feed = plugin.getRSS( from_buddy, category, if_mod==null?null:new String( if_mod, "UTF-8" ));
         
          res.put( "rss", feed.getContent());
         
          res.put( "last_mod", feed.getLastModified());
         
        }else{
         
          res.put( "torrent", plugin.getRSSTorrent( from_buddy, category, hash ));
        }
      }catch( BuddyPluginException e  ){
       
        throw( e );
       
      }catch( Throwable e ){
       
        throw( new BuddyPluginException( "Failed to handle rss", e ));
      }
    }else{
     
      throw( new BuddyPluginException( "Unrecognised request type " + type ));
    }
   
    logMessage( "AZ2 reply sent: " + from_buddy.getString() + " <- " + reply );

    return( reply );
  }
   
  public chatInstance
  createChat(
    BuddyPluginBuddy[]    buddies )
  {
    byte[]  id_bytes = new byte[20];
   
    RandomUtils.SECURE_RANDOM.nextBytes( id_bytes );
   
    String  id = Base32.encode( id_bytes );
   
    chatInstance  chat;
   
    synchronized( chats ){

      chat = new chatInstance( id );
     
      chats.put( id, chat );
    }
   
    logMessage( "Chat " + chat.getID() + " created" );

    informCreated( chat );
         
    chat.addParticipants( buddies, true );
   
    return( chat );
  }
 
  protected void
  destroyChat(
    chatInstance  chat )
  {
    synchronized( chats ){

      chats.remove( chat.getID());
    }
   
    logMessage( "Chat " + chat.getID() + " destroyed" );
   
    informDestroyed( chat );
  }
 
  protected void
  informCreated(
    chatInstance    chat )
  {
    Iterator  it = listeners.iterator();
   
    while( it.hasNext()){
     
      ((BuddyPluginAZ2Listener)it.next()).chatCreated( chat );
    }
  }
 
  protected void
  informDestroyed(
    chatInstance    chat )
  {
    Iterator  it = listeners.iterator();
   
    while( it.hasNext()){
     
      ((BuddyPluginAZ2Listener)it.next()).chatDestroyed( chat );
    }
  }
 
  public void
  sendAZ2Message(
    BuddyPluginBuddy  buddy,
    String        msg )
  {
    try{
      Map  request = new HashMap();
     
      request.put( "type", new Long( RT_AZ2_REQUEST_MESSAGE ));
      request.put( "msg", msg.getBytes());
     
      sendMessage( buddy, request );
       
    }catch( Throwable e ){
     
      logMessageAndPopup( "Send message failed", e );
    }
  }
 
  protected void
  sendAZ2Chat(
    BuddyPluginBuddy  buddy,
    Map          msg )
  {
    try{
      Map  request = new HashMap();
     
      request.put( "type", new Long( RT_AZ2_REQUEST_CHAT ));
      request.put( "msg", msg );
     
      sendMessage( buddy, request );
       
    }catch( Throwable e ){
     
      logMessageAndPopup( "Send message failed", e );
    }
  }
 
  public void
  sendAZ2Torrent(
    Torrent        torrent,
    BuddyPluginBuddy  buddy )
  {
    try{
     
      Map  request = new HashMap();
     
      request.put( "type", new Long( RT_AZ2_REQUEST_SEND_TORRENT ));
      request.put( "torrent", torrent.writeToBEncodedData());
     
      sendMessage( buddy, request );
     
    }catch( Throwable e ){
     
      logMessageAndPopup( "Send torrent failed", e );
    }
  }
 
  public void
  sendAZ2TrackerMessage(
    BuddyPluginBuddy            buddy,
    Map                    msg,
    final BuddyPluginAZ2TrackerListener    listener )
  {
    logMessage( "AZ2 request sent: " + buddy.getString() + " <- " + msg );

    try{
      Map  request = new HashMap();
     
      request.put( "type", new Long( RT_AZ2_REQUEST_TRACK ));
      request.put( "msg", msg );
     
      buddy.sendMessage(
        BuddyPlugin.SUBSYSTEM_AZ2,
        request,
        SEND_TIMEOUT,
        new BuddyPluginBuddyReplyListener()
        {
          public void
          replyReceived(
            BuddyPluginBuddy    from_buddy,
            Map            reply )
          {
            int type = ((Long)reply.get( "type")).intValue();
           
            if ( type != RT_AZ2_REPLY_TRACK ){
             
              sendFailed( from_buddy, new BuddyPluginException( "Mismatched reply type" ));
            }
           
            listener.messageReceived( from_buddy, (Map)reply.get( "msg" ));
          }
         
          public void
          sendFailed(
            BuddyPluginBuddy    to_buddy,
            BuddyPluginException  cause )
          {
            listener.messageFailed( to_buddy, cause );
          }
        });
       
    }catch( Throwable e ){
     
      logMessageAndPopup( "Send message failed", e );
    }
  }
 
  public void
  sendAZ2RSSMessage(
    BuddyPluginBuddy            buddy,
    Map                    msg,
    final BuddyPluginAZ2TrackerListener    listener )
  {
    logMessage( "AZ2 request sent: " + buddy.getString() + " <- " + msg );

    try{
      Map  request = new HashMap();
     
      request.put( "type", new Long( RT_AZ2_REQUEST_RSS ));
      request.put( "msg", msg );
     
      buddy.sendMessage(
        BuddyPlugin.SUBSYSTEM_AZ2,
        request,
        SEND_TIMEOUT,
        new BuddyPluginBuddyReplyListener()
        {
          public void
          replyReceived(
            BuddyPluginBuddy    from_buddy,
            Map            reply )
          {
            int type = ((Long)reply.get( "type")).intValue();
           
            if ( type != RT_AZ2_REPLY_RSS ){
             
              sendFailed( from_buddy, new BuddyPluginException( "Mismatched reply type" ));
            }
           
            listener.messageReceived( from_buddy, (Map)reply.get( "msg" ));
          }
         
          public void
          sendFailed(
            BuddyPluginBuddy    to_buddy,
            BuddyPluginException  cause )
          {
            listener.messageFailed( to_buddy, cause );
          }
        });
       
    }catch( Throwable e ){
     
      logMessage( "Send message failed", e );
    }
  }
 
  protected void
  sendMessage(
    BuddyPluginBuddy  buddy,
    Map          request )
 
    throws BuddyPluginException
  {
    logMessage( "AZ2 request sent: " + buddy.getString() + " <- " + request );

    buddy.getMessageHandler().queueMessage(
        BuddyPlugin.SUBSYSTEM_AZ2,
        request,
        SEND_TIMEOUT );   
  }
 
  public void
  addListener(
    BuddyPluginAZ2Listener    listener )
  {
    listeners.add( listener );
  }
 
  public void
  removeListener(
    BuddyPluginAZ2Listener    listener )
  {
    listeners.remove( listener );
  }
 
  public void
  addTrackerListener(
    BuddyPluginAZ2TrackerListener    listener )
  {
    track_listeners.add( listener );
  }
 
  public void
  removeTrackerListener(
    BuddyPluginAZ2TrackerListener    listener )
  {
    track_listeners.remove( listener );
  }
 
  protected void
  logMessageAndPopup(
    String    str,
    Throwable  e )
  {
    logMessageAndPopup( str + ": " + Debug.getNestedExceptionMessage(e));
  }
 
  protected void
  logMessageAndPopup(
    String    str )
  {
    logMessage( str );
   
    plugin.getPluginInterface().getUIManager().showMessageBox(
      "azbuddy.msglog.title", "!" + str + "!", UIManagerEvent.MT_OK );
  }
 
  protected void
  logMessage(
    String    str )
  {
    plugin.logMessage( str );
  }
 
  protected void
  logMessage(
    String    str,
    Throwable   e )
  {
    plugin.logMessage( str + ": " + Debug.getNestedExceptionMessage(e));
  }
 
  public class
  chatInstance
    extends BuddyPluginAdapter
  {
    private String    id;
   
    private Map        participants   = new HashMap();
    private CopyOnWriteList  listeners     = new CopyOnWriteList();
   
    private List      history      = new ArrayList();
   
    protected
    chatInstance(
      String    _id )
    {
      id    = _id;
     
      plugin.addListener( this );
    }
   
    public String
    getID()
    {
      return( id );
    }
   
    public void
    buddyAdded(
      BuddyPluginBuddy  buddy )
    {
      buddyChanged( buddy );
    }
   
    public void
    buddyRemoved(
      BuddyPluginBuddy  buddy )
    {
      chatParticipant p = getParticipant( buddy );
     
      if ( p != null ){
       
        Iterator it = listeners.iterator();
       
        while( it.hasNext()){
         
          try{
            ((BuddyPluginAZ2ChatListener)it.next()).participantRemoved( p );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
        }
      }
    }

    public void
    buddyChanged(
      BuddyPluginBuddy  buddy )
    {
      chatParticipant p = getParticipant( buddy );
     
      if ( p != null ){
     
        Iterator it = listeners.iterator();
     
        while( it.hasNext()){
         
          try{
            ((BuddyPluginAZ2ChatListener)it.next()).participantChanged( p );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
        }
      }
    }
   
    protected void
    process(
      BuddyPluginBuddy  from_buddy,
      Map          msg )
    {
      chatParticipant p = getOrAddParticipant( from_buddy );
     
      int  type = ((Long)msg.get( "type")).intValue();
     
      if ( type == CHAT_MSG_TYPE_TEXT ){
   
        Iterator it = listeners.iterator();
       
        synchronized( history ){
       
          history.add( new chatMessage( p.getName(), msg ));
         
          if ( history.size() > 128 ){
           
            history.remove(0);
          }
        }
       
        while( it.hasNext()){
         
          try{
            ((BuddyPluginAZ2ChatListener)it.next()).messageReceived( p, msg );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
        }
      }else if ( type == CHAT_MSG_TYPE_PARTICIPANTS_ADDED ){
       
        List added = (List)msg.get( "p" );
       
        for (int i=0;i<added.size();i++){
         
          Map  participant = (Map)added.get(i);
         
          String pk = new String((byte[])participant.get( "pk" ));
         
          if ( !pk.equals( plugin.getPublicKey())){
         
            addParticipant( pk );
          }
        }
      }
    }
   
    public void
    sendMessage(
      Map    msg )
    {
      msg.put( "type", new Long( CHAT_MSG_TYPE_TEXT ));
     
      sendMessageBase( msg );
    }
   
    protected void
    sendMessageBase(
      Map    msg )
    {
      Map  ps;
     
      synchronized( participants ){
       
        ps = new HashMap( participants );
      }
     
      msg.put( "id", id );
     
      Iterator it = ps.values().iterator();
     
      while( it.hasNext()){
       
        chatParticipant participant = (chatParticipant)it.next();
       
        if ( participant.isAuthorised()){
         
          sendAZ2Chat( participant.getBuddy(), msg );
        }
      }
    }
   
    public chatMessage[]
    getHistory()
    {
      synchronized( history ){
       
        chatMessage[]  res = new chatMessage[history.size()];
       
        history.toArray( res );
       
        return( res );
      }
    }
 
    protected chatParticipant
    getOrAddParticipant(
      BuddyPluginBuddy  buddy )
    {
      return( addParticipant( buddy ));
    }
   
    public chatParticipant
    addParticipant(
      String    pk )
    {
      chatParticipant p;
     
      BuddyPluginBuddy buddy = plugin.getBuddyFromPublicKey( pk );
     
      synchronized( participants ){
       
        p = (chatParticipant)participants.get( pk );

        if ( p != null ){
         
          return( p );
        }
       
        if ( buddy == null ){
       
          p = new chatParticipant( pk );
         
        }else{
         
          p = new chatParticipant( buddy );
        }
       
        participants.put( pk, p );
      }
     
      Iterator it = listeners.iterator();
     
      while( it.hasNext()){
       
        try{
          ((BuddyPluginAZ2ChatListener)it.next()).participantAdded( p );
         
        }catch( Throwable e ){
         
          Debug.printStackTrace(e);
        }
      }
     
      return( p );
    }
   
    public chatParticipant
    addParticipant(
      BuddyPluginBuddy  buddy )
    {
      return( addParticipant( buddy.getPublicKey()));
    }
   
    public void
    addParticipants(
      BuddyPluginBuddy[]    buddies,
      boolean          inform_others )
    {
      for (int i=0;i<buddies.length;i++ ){
       
        addParticipant( buddies[i] );
      }
     
      if ( inform_others ){
     
        Map  msg = new HashMap();
       
        msg.put( "type", new Long( CHAT_MSG_TYPE_PARTICIPANTS_ADDED ));
       
        List  added = new ArrayList();
       
        msg.put( "p", added );
       
        for ( int i=0;i<buddies.length;i++){
       
          Map map = new HashMap();
         
          map.put( "pk", buddies[i].getPublicKey());
         
          added.add( map );
        }
       
        sendMessageBase( msg );
      }
    }

    protected chatParticipant
    getParticipant(
      BuddyPluginBuddy  b )
    {
      String  pk = b.getPublicKey();
     
      synchronized( participants ){
       
        chatParticipant p = (chatParticipant)participants.get( pk );

        if ( p != null ){
         
          return( p );
        }
      }
     
      return( null );
    }
   
    public chatParticipant[]
    getParticipants()
    {
      synchronized( participants ){

        chatParticipant[]  res = new chatParticipant[participants.size()];
       
        participants.values().toArray( res );
       
        return( res );
      }
    }
   
    protected void
    removeParticipant(
      chatParticipant    p )
    {
      boolean  removed;
     
      synchronized( participants ){

        removed = participants.remove( p.getPublicKey()) != null;
      }
     
      if ( removed ){
       
        Iterator it = listeners.iterator();
       
        while( it.hasNext()){
         
          try{
            ((BuddyPluginAZ2ChatListener)it.next()).participantRemoved( p );
           
          }catch( Throwable e ){
           
            Debug.printStackTrace(e);
          }
        }
      }
    }
   
    public void
    destroy()
    {
      plugin.removeListener( this );

      destroyChat( this );
    }
   
    public void
    addListener(
      BuddyPluginAZ2ChatListener    listener )
    {
      listeners.add( listener );
    }
   
    public void
    removeListener(
      BuddyPluginAZ2ChatListener    listener )
    {
      listeners.remove( listener );
    }
  }
 
  public class
  chatParticipant
  {
    private BuddyPluginBuddy  buddy;
    private String        public_key;
   
    protected
    chatParticipant(
      BuddyPluginBuddy    _buddy )
    {
      buddy = _buddy;
    }
   
    protected
    chatParticipant(
      String      pk  )
    {
      public_key = pk;
    }
   
    public boolean
    isAuthorised()
    {
      return( buddy != null );
    }
   
    public BuddyPluginBuddy
    getBuddy()
    {
      return( buddy );
    }
   
    public String
    getPublicKey()
    {
      if ( buddy != null ){
       
        return( buddy.getPublicKey());
      }
     
      return( public_key );
    }
   
    public String
    getName()
    {
      if ( buddy != null ){
       
        return( buddy.getName());
      }
     
      return( public_key );
    }
  }
 
  public class
  chatMessage
  {
    private String    nick;
    private Map      map;
   
    protected
    chatMessage(
      String      _nick,
      Map        _map )
    {
      nick    = _nick;
      map      = _map;
    }
   
    public String
    getNickName()
    {
      return( nick );
    }
   
    public Map
    getMessage()
    {
      return( map );
    }
  }
}
TOP

Related Classes of com.aelitis.azureus.plugins.net.buddy.BuddyPluginAZ2$chatMessage

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.