Package hamsam.protocol.msn

Source Code of hamsam.protocol.msn.MsnProtocol

/*
* Hamsam - Instant Messaging API
* Copyright (C) 2003 Raghu K
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package hamsam.protocol.msn;

import hamsam.api.Buddy;
import hamsam.api.Conference;
import hamsam.api.IMListener;
import hamsam.api.Message;
import hamsam.api.SmileyComponent;
import hamsam.exception.IllegalArgumentException;
import hamsam.exception.IllegalStateException;
import hamsam.exception.UnsupportedOperationException;
import hamsam.net.ProxyInfo;
import hamsam.protocol.Protocol;

/**
* Implementation of MSN messenger protocol. This class implements the
* {@link hamsam.protocol.Protocol Protocol} interface so as to provide
* instant messaging and presence services via Hamsam API.
* <p>
* Users of the API should never use this class directly. They must use
* the {@link hamsam.protocol.ProtocolManager ProtocolManager} and
* {@link hamsam.protocol.Protocol Protocol} classes to access the MSN
* services indirectly.
*
* @author Raghu K
*/
public class MsnProtocol implements Protocol
{
  /**
   * All smileys supported by MSN.
   */
  private SmileyComponent[] smileys;

  /**
   * Processes all events received from MSN server.
   */
  private EventProcessor eventProcessor;

  /**
   * Listener for this protocol.
   */
  private IMListener listener;

  /**
   * The dispatch or notification server currently used by this
   * session.
   */
  private MsnServer server;

  /**
   * Passport of the user currently logged in.
   */
  private String username;

  /**
   * Password of the user currently logged in.
   */
  private String password;

  /**
   * Information about the proxy server to be used for all connections.
   */
  private ProxyInfo proxyInfo;

  /**
   * Default Constructor.
   */
  public MsnProtocol()
  {
    eventProcessor = new EventProcessor(this);
    smileys = Util.loadSmileys();
  }

  /**
   * Log in to the MSN server. If we are already logged in, this method will first
   * disconnect from MSN and then try to login.
   *
   * @param username the user id to log in.
   * @param password the password for authentication.
   * @param info     the proxy information explaining how to connect.
   *
   * @throws IllegalStateException if no listener is set using the
   *                               {@link #setListener(IMListener) setListener} method.
   */
  public synchronized void connect(String username, String password, ProxyInfo info) throws IllegalStateException
  {
    if(listener == null)
      throw new IllegalStateException("IMListener not set for this protocol");

    if(this.server instanceof NotificationServer)
      disconnect();

    this.username = username;
    this.password = password;
    this.proxyInfo = info;

    listener.connecting(this);

    try
    {
      this.server = new DispatchServer(this, eventProcessor, info);
    }
    catch(Exception e)
    {
      eventProcessor.connectFailed("Cannot connect: " + e.toString());
    }
  }

  /**
   * Change the status message for the user logged in for this protocol.
   * If <code>status</code> is <code>null</code>, the status is changed
   * to invisible.
   * <p>
   * MSN protocol supports only a limited range of status messages. If you
   * pass a status message which is not supported by MSN protocol, this
   * method throws an IllegalArgumentException. In order to get a complete list
   * of supported status messages, use the getSupportedStatusMessages() method.
   *
   * @param status                          the new status message.
   * @throws IllegalArgumentException       when the status message is invalid.
   * @throws IllegalStateException          if the protocol is not connected.
   * @see #getSupportedStatusMessages()     getSupportedStatusMessages()
   */
  public void changeStatus(String status) throws IllegalArgumentException, IllegalStateException
  {
    String code = Util.getStatusCode(status);
    if(code == null)
      throw new IllegalArgumentException("Invalid status message - " + status);

    if(server instanceof NotificationServer)
    {
      NotificationServer ns = (NotificationServer) server;
      ns.changeStatus(code);
    }
    else
      throw new IllegalStateException("Not yet connected to MSN");
  }

  /**
   * Disconnect from MSN messaging service. This is equivalent to
   * logging out from the service.
   *
   * @throws IllegalStateException if the protocol is not connected.
   */
  public void disconnect() throws IllegalStateException
  {
    if(!(server instanceof NotificationServer))
      throw new IllegalStateException("Not yet connected to MSN");

    server.shutdown();
    eventProcessor.disconnected();
  }

  /**
   * Returns the name of this protocol.
   *
   * @return the string "MSN".
   */
  public String getProtocolName()
  {
    return "MSN";
  }

  /**
   * Determines whether this protocol will notify you if a user attempts to
   * add you to his / her buddy list. This method always returns true.
   *
   * @return <code>true</code>.
   */
  public boolean isBuddyAddRequestSupported()
  {
    return true;
  }

  /**
   * Determines whether this protocol supports arranging buddies in
   * different groups. This method always returns true.
   *
   * @return <code>true</code>.
   */
  public boolean isBuddyGroupSupported()
  {
    return true;
  }

  /**
   * Determines whether this protocol supports ignoring
   * buddies. This method always returns true.
   *
   * @return <code>true</code>.
   */
  public boolean isIgnoreSupported()
  {
    return true;
  }

  /**
   * Determines whether this protocol supports sending and
   * receiving offline messages. This method always returns false;
   *
   * @return <code>false</code>.
   */
  public boolean isOfflineMessageSupported()
  {
    return false;
  }

  /**
   * Determines whether this protocol supports typing notifications.
   * This method always returns false.
   *
   * @return <code>false</code>.
   */
  public boolean isTypingNotifySupported()
  {
    return false;
  }

  /**
   * Determines whether this protocol supports conferences.
   * This method always returns true.
   *
   * @return <code>true</code>.
   * @see hamsam.api.Conference Conference
   */
  public boolean isConferenceSupported()
  {
    return true;
  }

  /**
   * Determines whether this protocol supports e-mail alerts.
   * This method always returns true.
   *
   * @return <code>true</code>.
   */
  public boolean isMailNotifySupported()
  {
    return true;
  }

  /**
   * Determines whether this protocol supports setting the status of the
   * user to invisible. This method always returns true.
   *
   * @return <code>true</code>.
   */
  public boolean isInvisibleSupported()
  {
    return true;
  }

  /**
   * Sets the listener for this protocol. This listener will be notified for
   * any instant message events that originates from MSN protocol.
   *
   * @param listener the listener for this protocol, pass <code>null</code>
   *                 to unregister the current listener.
   */
  public void setListener(IMListener listener)
  {
    this.listener = listener;
    eventProcessor.setListener(listener);
  }

  /**
   * Start a new conference by inviting some buddies. MSN protocol does not support
   * any invitation messages, hence <code>message</code> is always ignored.
   *
   * @param conf the conference which is to be started.
   * @param message the invitation message to be sent. This parameter is always ignored.
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  public void startConference(Conference conf, String message) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.startSBSession(conf);
  }

  /**
   * Disconnect the current user from a conference.
   *
   * @param conf the conference from which the user has to disconnect.
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  public void quitConference(Conference conf) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.quitSBSession(conf);
  }

  /**
   * Send a conference message.
   *
   * @param conf the conference to which the message is to be sent.
   * @param message the instant message to be sent.
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  public void sendConferenceMessage(Conference conf, Message message) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.sendConferenceMessage(conf, message);
  }

  /**
   * Add a buddy to your buddy list. The result of this operation
   * will be notified to the registered <code>IMListener</code>.
   *
   * @param buddy the buddy to be added.
   *
   * @see IMListener#buddyAddRequest(Buddy,Buddy,String) IMListener.buddyAddRequest
   * @see IMListener#buddyAdded(Buddy) IMListener.buddyAdded
   * @see IMListener#buddyAddFailed(Buddy,String) IMListener.buddyAddFailed
   *
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   * @throws IllegalArgumentException if the group of the buddy is not specified, or
   *                                  the specified group does not exist.
   */
  public void addToBuddyList(Buddy buddy) throws IllegalStateException, IllegalArgumentException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.addBuddyToForwardList(buddy);
  }

  /**
   * Delete a buddy from your buddy list. The result of this operation
   * will be notified to the registered <code>IMListener</code>.
   *
   * @param buddy the buddy to be deleted.
   *
   * @see IMListener#buddyDeleted(Buddy) IMListener.buddyDeleted
   * @see IMListener#buddyDeleteFailed(Buddy,String) IMListener.buddyDeleteFailed
   *
   * @throws IllegalArgumentException if the group of the buddy is not specified.
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  public void deleteFromBuddyList(Buddy buddy) throws IllegalArgumentException, IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.removeBuddyFromForwardList(buddy);
  }

  /**
   * Prevent a buddy from sending you messages. The result of this
   * operation will be notified to the registered <code>IMListener</code>.
   *
   * @param buddy the buddy to be ignored.
   *
   * @see IMListener#buddyIgnored(Buddy) IMListener.buddyIgnored
   * @see IMListener#buddyIgnoreFailed(Buddy,String) IMListener.buddyIgnoreFailed
   *
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  public void ignoreBuddy(Buddy buddy) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.addBuddyToBlockedList(buddy);
  }

  /**
   * Undo a previous ignore operation for a buddy. The result of this
   * operation will be notified to the registered <code>IMListener</code>.
   *
   * @param buddy the buddy to be ignored.
   *
   * @see IMListener#buddyUnignored(Buddy) IMListener.buddyUnignored
   * @see IMListener#buddyUnignoreFailed(Buddy,String) IMListener.buddyUnignoreFailed
   *
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */ 
  public void unignoreBuddy(Buddy buddy) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    ns.removeBuddyFromBlockedList(buddy);
  }

  /**
   * Send an instant message to a buddy.
   *
   * @param buddy the buddy to whom the message should be sent.
   * @param message the message to be sent.
   */
  public void sendInstantMessage(Buddy buddy, Message message) throws IllegalStateException
  {
    NotificationServer ns = checkValidNotificationServer();
    SwitchboardServer server = ns.getExistingSBSession(buddy);
    if(server == null)
      server = startSBSession(buddy);

    server.sendMessage(message);
  }

  /**
   * Notify this buddy that you have started typing.
   *
   * @param buddy the buddy to whom the typing notification is to be sent.
   *
   * @throws UnsupportedOperationException if this protocol does not support
   *                                       typing notifications.
   */
  public void typingStarted(Buddy buddy) throws UnsupportedOperationException
  {
    throw new UnsupportedOperationException("Typing notifications are not supported.");
  }

  /**
   * Notify this buddy that you have stopped typing.
   *
   * @param buddy the buddy to whom the typing notification is to be sent.
   *
   * @throws UnsupportedOperationException if this protocol does not support
   *                                       typing notifications.
   */
  public void typingStopped(Buddy buddy) throws UnsupportedOperationException
  {
    throw new UnsupportedOperationException("Typing notifications are not supported.");
  }

  /**
   * Returns an array of all SmileyComponents supported by this protocol.
   *
   * @return an array of all SmileyComponents supported by this protocol.
   */
  public SmileyComponent[] getSupportedSmileys()
  {
    return smileys;
  }

  /**
   * Returns an array of status messages supported by MSN protocol.
   *
   * @return array of status messages supported by MSN protocol
   */
  public String[] getSupportedStatusMessages()
  {
    return Util.getSupportedStatusMessages();
  }

  /**
   * Returns the passport of the current user.
   *
   * @return passport of the current user
   */
  String getUsername()
  {
    return username;
  }

  /**
   * Returns the password of the current user.
   *
   * @return password of the current user
   */
  String getPassword()
  {
    return password;
  }

  /**
   * Invoked by dispatch server for connecting to notification server.
   *
   * @param connect the host name and port number to connect to, separated
   * by colon.
   */
  void switchServer(String connect)
  {
    int index = connect.indexOf(':');
    if(index != -1)
    {
      try
      {
        String host = connect.substring(0, index);
        int port = Integer.parseInt(connect.substring(index + 1));
        this.server = new NotificationServer(this, eventProcessor, host, port, proxyInfo);
      }
      catch(NumberFormatException e)
      {
        eventProcessor.connectFailed("Invalid server name and port: " + connect);
      }
      catch(Exception e)
      {
        eventProcessor.connectFailed("I/O Error: " + e.toString());
      }
    }
    else
      eventProcessor.connectFailed("Invalid server name and port: " + connect);
  }

  /**
   * Returns the proxy information object.
   *
   * @return the <code>ProxyInfo</code> to be used for all connections.
   */
  ProxyInfo getProxyInfo()
  {
    return proxyInfo;
  }

  /**
   * Invoked when an SB session terminates abnormally.
   *
   * @param server the SB server that terminated.
   */
  void switchBoardTerminated(SwitchboardServer server)
  {
    try
    {
      NotificationServer ns = checkValidNotificationServer();
      ns.switchBoardTerminated(server);
    }
    catch(IllegalStateException e)
    {
      // This will never be thrown
    }
  }

  /**
   * Returns the notification server object to which this protocol is
   * currently connected. If it is not connected yet, this method throws
   * an exception.
   *
   * @return the notification server we are currently connected to.
   * @throws IllegalStateException if the protocol is not connected to MSN yet.
   */
  private NotificationServer checkValidNotificationServer() throws IllegalStateException
  {
    if(!(server instanceof NotificationServer))
      throw new IllegalStateException("Not logged in yet - MSN");

    return (NotificationServer) server;
  }

  private SwitchboardServer startSBSession(Buddy buddy) throws IllegalStateException
  {
    try
    {
      NotificationServer ns = checkValidNotificationServer();
      Buddy host = new Buddy(this, username);
      Buddy[] participants = new Buddy[2];
      participants[0] = host;
      participants[1] = buddy;
      Conference conf = new Conference(this, host, participants);
      ns.startSBSession(conf);

      // Wait till we get an SB session for this
      return ns.waitForSBSession(conf);
    }
    catch(UnsupportedOperationException e)
    {
      // We will not get this
    }
    catch(IllegalArgumentException e)
    {
      // We will not get this
    }

    // We will never reach here
    return null;
  }

  /**
   * Checks whether this protocol supports buddy aliases.
   *
   * @return <code>true</code>
   */
  public boolean isBuddyNameAliasSupported()
  {
    return true;
  }

  /**
   * Changes the alias of a buddy.
   *
   * @param buddy the buddy whose alias needs to be changed.
   * @param alias the new alias of this buddy.
   * @see #isBuddyNameAliasSupported() isBuddyNameAliasSupported()
   */
  public void changeBuddyAlias(Buddy buddy, String alias)
  {
    // TODO Auto-generated method stub
  }
}
TOP

Related Classes of hamsam.protocol.msn.MsnProtocol

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.