Package net.sphene.goim.rcp.xmpp

Source Code of net.sphene.goim.rcp.xmpp.XMPPManager

/*
* Gamers Own Instant Messenger
* Copyright (C) 2005-2006 Herbert Poul (kahless@sphene.net)
* http://goim.sphene.net
*
* 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, or
* (at your option) any later version.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package net.sphene.goim.rcp.xmpp;

import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sphene.goim.rcp.GOIMPlugin;
import net.sphene.goim.rcp.beans.GOIMAccount;
import net.sphene.goim.rcp.beans.GOIMGameItem;
import net.sphene.goim.rcp.beans.GOIMGameList;
import net.sphene.goim.rcp.beans.GOIMRosterEvent;
import net.sphene.goim.rcp.beans.GOIMRosterListener;
import net.sphene.goim.rcp.beans.GameStatusChangeEvent;
import net.sphene.goim.rcp.preferences.PreferenceConstants;
import net.sphene.goim.rcp.ui.wizard.authrequested.AuthRequestedWizardDialog;
import net.sphene.goim.rcp.xmpp.util.FileTransferUtil;
import net.sphene.goim.rcp.xmpp.util.MUCUtils;
import net.sphene.goim.rcp.xmpp.util.MUCUtils.MUCRoom;
import net.sphene.libs.SpheneListener;
import net.sphene.libs.SpheneListenerList;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.jivesoftware.smack.AccountManager;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.RosterListener;
import org.jivesoftware.smack.SSLXMPPConnection;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Registration;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.filetransfer.FileTransferListener;
import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jivesoftware.smackx.filetransfer.FileTransferRequest;
import org.jivesoftware.smackx.filetransfer.IncomingFileTransfer;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.packet.Version;

public class XMPPManager {
  protected GOIMAccount account;
 
  protected XMPPConnection conn;
  protected Roster roster;
 
  protected Presence lastPresenceSent;
 
  public SpheneListenerList<StatusChangedEvent,SpheneListener<StatusChangedEvent>> ownPresenceChanged = new SpheneListenerList<StatusChangedEvent,SpheneListener<StatusChangedEvent>>();
  public SpheneListenerList<GOIMRosterEvent,GOIMRosterListener> rosterListener = new SpheneListenerList<GOIMRosterEvent,GOIMRosterListener>();
 
  protected ServiceDiscoveryManager disco;
 
  protected GOIMGameList gameList;
 
 
  public XMPPManager(GOIMAccount account) {
    this.account = account;
    this.gameList = GOIMPlugin.getPreferenceObject(GOIMGameList.class);
  }
  public XMPPConnection getConnection() { return conn; }
  public GOIMAccount getAccount() { return account; }
  public void connect(final Presence.Type type, final Presence.Mode mode) {
    new Thread() {
      public void run() {
        try {
          XMPPConnection.DEBUG_ENABLED = GOIMPlugin.getDefault().getMyPreferenceStore().getBoolean(PreferenceConstants.P_ENABLE_SMACK_DEBUGGING);
          ServiceDiscoveryManager.setIdentityName("GOIM " + Platform.getProduct().getDefiningBundle().getHeaders().get("Bundle-Version"));

          Roster.setDefaultSubscriptionMode(Roster.SUBSCRIPTION_MANUAL);
          //conn = new XMPPConnection(account.getServer());
          if(conn != null) conn.close();
          createConnection();
          if(!conn.isConnected()) { System.out.println("Not connected ?!"); }
          account.gotConnection();
          MultiUserChat.addInvitationListener(conn,new InvitationListener() {
            public void invitationReceived(final XMPPConnection conn, final String room, final String inviter, final String reason, final String password, final Message message) {
              PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                public void run() {
                  IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
                  if(window == null) window = PlatformUI.getWorkbench().getWorkbenchWindows()[0];
                  boolean join = MessageDialog.openQuestion(window.getShell(),inviter + " invites you to the MUC room " + room,inviter + " invites you to the MUC room " + room + ": '" + reason + "' - Accept invitation ?");
                  if(join) {
                    MUCUtils.joinMUCRoom(account,room,password);
                  } else {
                    MultiUserChat.decline(conn,room,inviter,"User rejected Invitation (Not asked for a reason)");
                  }
                }
              });
            }
          });
          FileTransferManager fileTransferManager = new FileTransferManager(conn);
          fileTransferManager.addFileTransferListener(new FileTransferListener() {
            public void fileTransferRequest(final FileTransferRequest request) {
              PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                public void run() {
                  Shell parent = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
                  boolean accept = MessageDialog.openConfirm(parent,
                      "Incoming File Transfer",
                      "You are receiving an incoming file transfer request from " +
                      request.getRequestor() + ", who wants to send you the file: " +
                      request.getFileName() + " (" + request.getFileSize() + " Bytes):\n" +
                      request.getDescription() + "\n" + "Would you like to accept it?");
                  if(!accept) return;
                  FileDialog fileDialog = new FileDialog(parent,SWT.SINGLE|SWT.SAVE);
                  fileDialog.setFileName(request.getFileName());
                  fileDialog.setText("Select Destination to save received file.");
                  String file = fileDialog.open();
                  if(file == null) return;
                  IncomingFileTransfer fileTransfer = request.accept();
                  try {
                    fileTransfer.recieveFile(new File(file));
                    FileTransferUtil.showProgressMonitor(parent,fileTransfer,"Receiving file " + request.getFileName());
                  } catch (Exception e) {
                    throw new RuntimeException("Error while receiving file: " + e.getLocalizedMessage(),e);
                  }
                }
              });
            } });
          conn.addPacketListener(new PacketListener(){
            public void processPacket(Packet packet) {
              //System.out.println("Got Packet from " + packet.getFrom() + " : " + packet.getClass().toString() + " :  " + packet.toString());
              if(packet instanceof Message) {
                account.chatWindowExtensionManager.handleMessage((Message)packet);
              } else if(packet instanceof Presence) {
                Presence presence = (Presence)packet;
                if(presence.getType() == Presence.Type.SUBSCRIBE) {
                  askForSubscribePermission(presence);
                }
              } else if(packet instanceof Version) {
                Version version = (Version)packet;
                if(version.getType() == IQ.Type.GET) {
                  Version reply = new Version();
                  reply.setType(IQ.Type.RESULT);
                  reply.setTo(version.getFrom());
                  reply.setName("GOIM (Gamers Own Instant Messenger)");
                  reply.setVersion((String)Platform.getProduct().getDefiningBundle().getHeaders().get("Bundle-Version"));
                  reply.setOs(System.getProperty("os.name") + " " + System.getProperty("os.version") + " (Java: " + System.getProperty("java.vendor") + " " + System.getProperty("java.version") + ")");
                  conn.sendPacket(reply);
                }
              }
            }},new AndFilter());
          conn.addConnectionListener(new ConnectionListener() {
            public void connectionClosed() {
            }
            public void connectionClosedOnError(final Exception e) {
              conn = null;
              Presence previousPresence = lastPresenceSent;
              lastPresenceSent = null;
              ownPresenceChanged.fireEvent(new StatusChangedEvent(this,previousPresence));
              PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                public void run() {
                  ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),"Error while logging in","Error during connection with jabber server: " + account.getServer() + e.getLocalizedMessage(),new Status(IStatus.ERROR,GOIMPlugin.ID,IStatus.OK,"Error while connected with account " + account.name,e));
                }
              });
            }});
          doLogin(type, mode);
        } catch (final XMPPException e) {
          e.printStackTrace();
          final XMPPError error = e.getXMPPError();
          if(false && error != null && error.getCode() == 401) {
//            MessageBox box = new MessageBox(GOIMPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
//            box.setMessage("Could not log in .. (401 Unauthorized) Trying to register ?");
//            int test = box.open();
//            if(test != SWT.OK) return;
            try {
              PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
                public void run() {
                }});
              tryRegister();
              doLogin(type,mode);
            } catch (XMPPException e1) {
              e1.printStackTrace();
              return;
            }
          } else {
            if(conn != null)
              conn.close();
            conn = null;
            lastPresenceSent = null;
            PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
              public void run() {
                ErrorDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),"Error while logging in","Error while trying to log into jabber server: " + account.getServer() + (error == null ? "" : ": " + error.getMessage()),new Status(IStatus.ERROR,GOIMPlugin.ID,IStatus.OK,"Error while logging into account " + account.name,e));
              }
            });
          }
        }
      }
    }.start();
  }
  public void tryRegister() throws XMPPException {
    if(conn != null) conn.close();
    createConnection();
    AccountManager manager = new AccountManager(conn);
    manager.createAccount(account.getUsername(),account.password);
    conn.close();
    conn = null;
  }
  public void createConnection() throws XMPPException {
    if(account.useSSL)
      conn = new SSLXMPPConnection(account.getServer(),account.getPort(),StringUtils.parseServer(account.jid));
    else
      conn = new XMPPConnection(account.getServer(),account.getPort(),StringUtils.parseServer(account.jid));
  }
  public IQ sendIQPacketAndWaitForReply(IQ reg) throws XMPPException {
    PacketFilter filter = new AndFilter(new PacketIDFilter(reg
        .getPacketID()), new PacketTypeFilter(IQ.class));
    PacketCollector collector = conn
        .createPacketCollector(filter);
    conn.sendPacket(reg);
    IQ result = (IQ) collector.nextResult(SmackConfiguration
        .getPacketReplyTimeout());
    // Stop queuing results
    collector.cancel();
        if (result == null) {
            throw new XMPPException("No response from server.");
        }
        else if (result.getType() == IQ.Type.ERROR) {
            throw new XMPPException(result.getError());
        }
    return result;
  }
  public Shell workbenchShell;
  public void askForSubscribePermission(final Presence presence) {
    if(StringUtils.parseBareAddress(presence.getFrom()).equals(GOIMAccount.STATSCONTACTJID)) {
      Presence reply = new Presence(Presence.Type.SUBSCRIBED);
      reply.setTo(presence.getFrom());
      conn.sendPacket(reply);
      Presence requestSubscribe = new Presence(Presence.Type.SUBSCRIBE);
      requestSubscribe.setTo(presence.getFrom());
      conn.sendPacket(requestSubscribe);
      return;
    }
    if(workbenchShell == null) workbenchShell = account.getDefaultShell();
    workbenchShell.getDisplay().asyncExec(new Runnable() {
      public void run() {
        new AuthRequestedWizardDialog(null,account,presence.getFrom()).open();
//        MessageDialog dialog = new MessageDialog(
//            workbenchShell,
//            "Subscribe Request",
//            null,
//            presence.getFrom() + " is requesting subscribe authorization for " + account.jid + ".",
//            MessageDialog.QUESTION,
//            new String[] { "Decline", "Auth + Add" },
//            1);
//        dialog.setBlockOnOpen(true);
//        int r = dialog.open();
//        Presence reply = null;
//        if(r == 1)
//          reply = new Presence(Presence.Type.SUBSCRIBED);
//        else
//          reply = new Presence(Presence.Type.UNSUBSCRIBED);
//        if(r == 1) {
//          ItemType itemType = getRoster().getEntry(StringUtils.parseBareAddress(presence.getFrom())).getType();
//          if(itemType != ItemType.TO && itemType != ItemType.BOTH) {
//            //getRoster().createEntry(presence.getFrom(),null,null);
//            Presence requestSubscribe = new Presence(Presence.Type.SUBSCRIBE);
//            requestSubscribe.setTo(presence.getFrom());
//            conn.sendPacket(requestSubscribe);
//          }
//        }
//        reply.setTo(presence.getFrom());
//        conn.sendPacket(reply);
      }
    });
  }
  Presence presenceByUser = null;
  public void changeStatus(Presence.Type type, Presence.Mode mode, boolean byuser) {
    if(type == Presence.Type.UNAVAILABLE) {
      Presence previousPresence = lastPresenceSent;
      conn.close();conn = null;lastPresenceSent = null;roster = null;
      ownPresenceChanged.fireEvent(new StatusChangedEvent(this,previousPresence));
      rosterListener.fireEvent(new GOIMRosterEvent(XMPPManager.this,GOIMRosterEvent.TYPE_MODIFIED, null));
      return;
    }
    Presence presence = new Presence(type);
    presence.setMode(mode);
    StringBuffer status = new StringBuffer();
    boolean changestate = false;
    String changeStateTo = GOIMPlugin.getDefault().getMyPreferenceStore().getString(PreferenceConstants.P_CHANGE_STATUS_TO_ON_GAME_LAUNCH);
    for(GOIMGameItem game : gameList) {
      String str = game.retrieveExtensionProxy().getStatusString(game);
      PacketExtension ex = game.retrieveExtensionProxy().getStatusPacket(game);
      if(str != null) status.append(str).append(" ");
      if(ex != null) presence.addExtension(ex);
      if(game.retrieveExtensionProxy().needsOnlineStatusChange(game))
        changestate = true;
    }
    if(!byuser && (presenceByUser == null || presenceByUser.getMode() == Presence.Mode.AVAILABLE)) {
      if(changestate) {
        if(!changeStateTo.equals(""))
          presence.setMode(Presence.Mode.fromString(changeStateTo));
      } else {
        presence.setMode(presenceByUser.getMode());
      }
    }
    String statusMsg = status.toString();
    if(!statusMsg.equals("")) statusMsg = "Currently Playing: " + statusMsg + " (visit http://goim.sphene.net)";
    if(status.length() > 0) presence.setStatus(statusMsg);
    presence.setPriority(account.resourcePriority);
    conn.sendPacket(presence);
    Presence previousPresence = lastPresenceSent;
    lastPresenceSent = presence;
    if(byuser) presenceByUser = presence;
    ownPresenceChanged.fireEvent(new StatusChangedEvent(this,previousPresence));
  }
  public Presence getOwnPresence() { return lastPresenceSent; }
  public Roster getRoster() { if(roster == null) return (conn == null ? null : conn.getRoster()); else return roster; }

  public boolean isConnected() {
    return conn != null && conn.isConnected();
  }
  public ServiceDiscoveryManager getDiscoManager() { return disco; }
  private void doLogin(final Presence.Type type, final Presence.Mode mode) throws XMPPException {
    conn.login(account.getUsername(),account.password,account.resource);
    disco = ServiceDiscoveryManager.getInstanceFor(conn);
    disco.addFeature("jabber:iq:version");
    changeStatus(type,mode,true);
    roster = conn.getRoster();
    roster.addRosterListener(new RosterListener(){
      public void rosterModified() {
//        System.out.println("rosterModified()");
        rosterListener.fireEvent(new GOIMRosterEvent(XMPPManager.this,GOIMRosterEvent.TYPE_MODIFIED,null));
      }
      public void presenceChanged(String jid) {
//        System.out.println("Presence Changed: " + jid);
        rosterListener.fireEvent(new GOIMRosterEvent(XMPPManager.this,GOIMRosterEvent.TYPE_PRESENCE_CHANGED,jid));
      }
      // TODO Find a better solution for this .. maybe forward all of the three events !
      // (Since smack 2.1 the rosterModified() method is split up in the following three methods)
      public void entriesAdded(Collection arg0) {
        rosterModified();
      }
      public void entriesUpdated(Collection arg0) {
        rosterModified();
      }
      public void entriesDeleted(Collection arg0) {
        rosterModified();
      }});
    rosterListener.fireEvent(new GOIMRosterEvent(XMPPManager.this,GOIMRosterEvent.TYPE_MODIFIED,null));
    GOIMPlugin.gameStatusChanged.addListener(new SpheneListener<GameStatusChangeEvent>() {
      public void handleEvent(GameStatusChangeEvent event) {
        changeStatus(lastPresenceSent.getType(),lastPresenceSent.getMode(),false);
      }
    });
   
    List<MUCRoom> list = MUCUtils.getAutoJoinList(account);
    if(list != null)
      for(MUCRoom room : list) {
        MUCUtils.joinMUCRoom(account,room);
      }
  }
  public void removeContact(RosterEntry selectedEntry, Shell shell) {
    if(!GOIMPlugin.getDefault().getMyPreferenceStore().getString(PreferenceConstants.CONTACTLIST_CONFIRM_REMOVE_ENTRY_TOGGLE).equals(MessageDialogWithToggle.ALWAYS)) {
      MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm(
          shell,
          "Remove Entry",
          "Are you sure you want to remove the entry " + (selectedEntry.getName() == null ? selectedEntry.getUser() : selectedEntry.getName()),
          null,
          false,
          GOIMPlugin.getDefault().getMyPreferenceStore(),
          PreferenceConstants.CONTACTLIST_CONFIRM_REMOVE_ENTRY_TOGGLE
          );
      if(dialog.getReturnCode() != IDialogConstants.OK_ID) return;
    }
    if(selectedEntry.getUser().indexOf('@') == -1) {
      Registration reg = new Registration();
      Map<String,String> map = new HashMap<String,String>();
      map.put("remove","");
      reg.setAttributes(map);
      reg.setType(IQ.Type.SET);
      reg.setTo(selectedEntry.getUser());
      conn.sendPacket(reg);
    }
    try {
      getRoster().removeEntry(selectedEntry);
    } catch (XMPPException e) {
      ErrorDialog.openError(shell,"Error while removing Entry","Error while removing entry: " + e.toString(),new Status(Status.ERROR,GOIMPlugin.ID,Status.OK,"Error while Removing Entry",e));
      e.printStackTrace();
    }
  }
}
TOP

Related Classes of net.sphene.goim.rcp.xmpp.XMPPManager

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.