Package jetbrains.communicator.jabber.impl

Source Code of jetbrains.communicator.jabber.impl.JabberFacadeImpl$SmackConnectionListener

/*
* Copyright 2000-2006 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.communicator.jabber.impl;

import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.ContainerUtil;
import com.thoughtworks.xstream.XStream;
import jetbrains.communicator.core.users.PresenceMode;
import jetbrains.communicator.core.users.UserPresence;
import jetbrains.communicator.ide.IDEFacade;
import jetbrains.communicator.jabber.AccountInfo;
import jetbrains.communicator.jabber.ConnectionListener;
import jetbrains.communicator.jabber.JabberFacade;
import jetbrains.communicator.jabber.VCardInfo;
import jetbrains.communicator.util.StringUtil;
import jetbrains.communicator.util.WaitFor;
import jetbrains.communicator.util.XMLUtil;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jetbrains.annotations.NonNls;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.packet.VCard;
import org.picocontainer.Disposable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* @author Kir
*/
public class JabberFacadeImpl implements JabberFacade, Disposable {
  @NonNls
  private static final Logger LOG = Logger.getLogger(JabberFacadeImpl.class);

  public static final String FILE_NAME = "jabberSettings.xml";
  private JabberSettings mySettings;
  private final IDEFacade myIdeFacade;
  private XStream myXStream;

  private final List<ConnectionListener> myConnectionListeners = ContainerUtil.createLockFreeCopyOnWriteList();
  private XMPPConnection myConnection;

  public JabberFacadeImpl(IDEFacade ideFacade) {
    myIdeFacade = ideFacade;
  }

  private void initSettingsIfNeeded() {
    if (mySettings == null) {
      myXStream = XMLUtil.createXStream();
      mySettings = (JabberSettings) XMLUtil.fromXml(myXStream, myIdeFacade.getConfigDir(), FILE_NAME, false);
      if (mySettings == null) {
        mySettings = new JabberSettings();
      }
    }
  }

  public void dispose() {
    disconnect();
  }

  public void disconnect() {
    if (myConnection != null && myConnection.isConnected()) {
      myConnection.close();
    }
    myConnection = null;
  }

  public String[] getServers() {
    SAXBuilder saxBuilder = new SAXBuilder();
    try {
      Document document = saxBuilder.build(getClass().getResource("servers.xml"));
      Element rootElement = document.getRootElement();
      List children = rootElement.getChildren("item", rootElement.getNamespace());
      List<String> result = new ArrayList<String>();
      for (Object aChildren : children) {
        Element element = (Element) aChildren;
        result.add(element.getAttributeValue("jid"));
      }
      return ArrayUtil.toStringArray(result);
    } catch (JDOMException e) {
      LOG.error(e.getMessage(), e);
    } catch (IOException e) {
      LOG.error(e.getMessage(), e);
    }
    return new String[]{"jabber.org"};
  }

  public AccountInfo getMyAccount() {
    initSettingsIfNeeded();
    return mySettings.getAccount();
  }

  public String connect() {
    if (isConnectedAndAuthenticated()) return null;
    AccountInfo info = getMyAccount();
    if (info == null || !info.isLoginAllowed()) return null;
    return connect(info.getUsername(), info.getPassword(), info.getServer(), info.getPort(), info.isForceSSL());
  }

  public String connect(String username, String password, String server, int port, boolean forceOldSSL) {
    return _createConnection(server, port, username, password, false, forceOldSSL);
  }

  public String createAccountAndConnect(String username, String password, String server, int port, boolean forceOldSSL) {
    return _createConnection(server, port, username, password, true, forceOldSSL);
  }

  private String _createConnection(String server, int port, final String username, String password, boolean createAccount, boolean forceOldSSL) {
    try {
      initSettingsIfNeeded();
     
      XMPPConnection.addConnectionListener(new ConnectionEstablishedListener() {
        public void connectionEstablished(XMPPConnection connection) {
          XMPPConnection.removeConnectionListener(this);
          fireConnected(connection);
        }
      });

      String serviceName = server;
      if ("talk.google.com".equals(server)) {
        serviceName = "gmail.com";
      }

      String user = username;
      int at = username.indexOf('@');
      if (at > 0) {
        serviceName = username.substring(at + 1);
        user = username.substring(0, at);
      }

      XMPPConnection connection;
      if (forceOldSSL) {
        connection = new SSLXMPPConnection(server, port, serviceName);
      }
      else {
        connection = new XMPPConnection(server, port, serviceName);
      }

      if (createAccount && connection.getAccountManager().supportsAccountCreation()) {
        connection.getAccountManager().createAccount(user, password.replaceAll("&", "&amp;"));
      }

      if (!connection.isConnected()) return StringUtil.getMsg("unable.to.connect.to", server, port);
      connection.login(user, password, IDETALK_RESOURCE);

      saveAccountData(server, port, username, password, forceOldSSL);

      if (rosterIsNotAvailable(connection)) {
        connection.close();
        return StringUtil.getMsg("no.roster.try.again");
      }

      myConnection = connection;

      fireAuthenticated();
      myConnection.addConnectionListener(new SmackConnectionListener());
    } catch (XMPPException e) {
      String message = getMessage(e);
      if (message != null && (message.indexOf("authentication failed") == -1 || password.length() != 0)) {
        LOG.info(message, e);
      }
      return message;
    } catch (IllegalStateException e) {
      LOG.info(e, e);
      return e.getMessage();
    }

    return null;
  }

  private boolean rosterIsNotAvailable(final XMPPConnection connection) {
    new WaitFor(3000) {
      protected boolean condition() {
        return connection.getRoster() != null;
      }
    };
    return connection.getRoster() == null;
  }

  private String getMessage(XMPPException e) {
    return e.getXMPPError() == null ? e.getMessage() : e.getXMPPError().toString();
  }

  private void saveAccountData(String server, int port, String username, String password, boolean forceOldSSL) {
    getMyAccount().setServer(server);
    getMyAccount().setPort(port);
    getMyAccount().setUsername(username);
    getMyAccount().setPassword(password);
    getMyAccount().setForceSSL(forceOldSSL);
  }

  public void setVCardInfo(String nickName, String firstName, String lastName) throws XMPPException {
    assert isConnectedAndAuthenticated() : "Not connected or authenticated";
    VCard vCard = new VCard();
    vCard.setFirstName(firstName);
    vCard.setLastName(lastName);
    vCard.setNickName(nickName);

    PacketCollector collector = myConnection.createPacketCollector(new PacketIDFilter(vCard.getPacketID()));
    vCard.save(myConnection);

    IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
    collector.cancel();

    if (response == null) {
      throw new XMPPException("No response from the server.");
    }
    // If the server replied with an error, throw an exception.
    else if (response.getType() == IQ.Type.ERROR) {
      throw new XMPPException(response.getError());
    }
  }

  public VCardInfo getVCard(String jabberId) {
    assert isConnectedAndAuthenticated() : "Not connected or authenticated";
    VCard vCard = new VCard();
    try {
      if (jabberId == null) {
        vCard.load(myConnection);
      } else {
        vCard.load(myConnection, jabberId);
      }
    } catch (XMPPException e) {
      return new VCardInfo("N/A", "N/A", "N/A");
    }
    return new VCardInfo(vCard.getFirstName(), vCard.getLastName(), vCard.getNickName());
  }

  public boolean isConnectedAndAuthenticated() {
    return myConnection != null && myConnection.isAuthenticated();
  }

  public XMPPConnection getConnection() {
    return myConnection;
  }

  public void changeSubscription(String from, boolean subscribe) {
    LOG.info((subscribe ? "Accepted": "Denied" ) + " adding self to " + from + "'s contact list.");
    changeSubscription(from, subscribe ? Presence.Type.subscribed : Presence.Type.unsubscribed);
  }

  private void changeSubscription(String user, Presence.Type type) {
    Presence reply = new Presence(type);
    reply.setTo(user);
    myConnection.sendPacket(reply);
  }

  public void setOnlinePresence(UserPresence userPresence) {
    final Presence.Mode mode;
    String status = "";
    PresenceMode presenceMode = userPresence.getPresenceMode();
    switch(presenceMode) {
      case AWAY:
        mode = Presence.Mode.away;
        break;
      case EXTENDED_AWAY:
        mode = Presence.Mode.xa;
        break;
      case DND: mode = Presence.Mode.dnd; break;
      default: mode = Presence.Mode.available;
    }
    Presence presence = new Presence(Presence.Type.available, status, 0, mode);
    myConnection.sendPacket(presence);
  }

  public void saveSettings() {
    initSettingsIfNeeded();
    if (!mySettings.getAccount().shouldRememberPassword()) {
      mySettings.getAccount().setPassword("");
    }
    XMLUtil.toXml(myXStream, myIdeFacade.getConfigDir(), FILE_NAME, mySettings);
  }

  public void addUsers(String group, List<String> list) {
    if (!isConnectedAndAuthenticated()) return;
   
    String self = getConnection().getUser();
    for (String id : list) {
      if (!self.startsWith(id)) {
        try {
          Roster roster = getConnection().getRoster();
          RosterEntry oldEntry = roster.getEntry(id);
          if (oldEntry != null) {
            roster.removeEntry(oldEntry);
          }
          roster.createEntry(id, JabberTransport.getSimpleId(id), new String[]{group});
        } catch (XMPPException e) {
          myIdeFacade.showMessage(StringUtil.getMsg("jabber.error.while.adding.user.title", id)
              ,StringUtil.getMsg("jabber.error.while.adding.user.text", id, getMessage(e))
          );
          LOG.info(getMessage(e), e);
        }
      }
    }
  }

  public void addConnectionListener(ConnectionListener connectionListener) {
    myConnectionListeners.add(connectionListener);
  }

  public void removeConnectionListener(ConnectionListener connectionListener) {
    myConnectionListeners.remove(connectionListener);
  }

  protected void fireConnected(XMPPConnection connection) {
    for (ConnectionListener listener : myConnectionListeners) {
      listener.connected(connection);
    }
  }

  protected void fireAuthenticated() {
    for (ConnectionListener listener : myConnectionListeners) {
      listener.authenticated();
    }
  }

  protected void fireDisconnected(boolean onError) {
    for (ConnectionListener listener : myConnectionListeners) {
      listener.disconnected(onError);
    }
  }

  private class SmackConnectionListener implements org.jivesoftware.smack.ConnectionListener {
    public void connectionClosed() {
      myConnection.removeConnectionListener(this);
      fireDisconnected(false);
    }

    public void connectionClosedOnError(Exception exception) {
      try {
        myConnection.removeConnectionListener(this);
      } finally {
        fireDisconnected(true);
      }
    }

    public void reconectionSuccessful() {
    }

    public void reconnectingIn(int seconds) {
    }

    public void reconnectionFailed(Exception e) {
      try {
        myConnection.removeConnectionListener(this);
      } finally {
        fireDisconnected(true);
      }
    }

  }
}
TOP

Related Classes of jetbrains.communicator.jabber.impl.JabberFacadeImpl$SmackConnectionListener

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.