package de.uni_passau.fim.pkjab.model; import java.io.IOException; import java.util.Iterator; import java.util.Set; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; import de.uni_passau.fim.pkjab.model.messages.Message; import de.uni_passau.fim.pkjab.model.tags.AbstractXMLTag; import de.uni_passau.fim.pkjab.model.tags.Iq; import de.uni_passau.fim.pkjab.model.xmpp.XMPPAuthHandler; import de.uni_passau.fim.pkjab.model.xmpp.XMPPWriter; import de.uni_passau.fim.pkjab.util.ConnectionState; import de.uni_passau.fim.pkjab.util.Jid; import de.uni_passau.fim.pkjab.util.Observable; import de.uni_passau.fim.pkjab.util.Observer; import de.uni_passau.fim.pkjab.util.UserState; public class Connection extends Observable { protected final ConnectionCallback callback = new ConnectionCallback(this); ConnectionState state = ConnectionState.OFFLINE; private ConnectionThread thread = null; private final Roster roster = new Roster(); Jid jid; final String server; final int port; final String password; private UserState userState = UserState.ONLINE; public Connection(Jid user, String password) { this(user, password, user.getDomain(), 5222); } public Connection(Jid user, String password, String server, int port) { this.server = server; this.port = port; this.jid = user; this.password = password; } public synchronized void connect() { if (!isConnected() && (state == ConnectionState.OFFLINE)) { state = ConnectionState.CONNECTING; try { (thread = new ConnectionThread(this)).start(); } catch (SAXException e) { // no XML parser available e.printStackTrace(); state = ConnectionState.OFFLINE; thread = null; } } } public synchronized void disconnect() { if ((state != ConnectionState.OFFLINE) && (state != ConnectionState.DISCONNECTING)) { if (state == ConnectionState.ONLINE) { try { thread.getOutput().sendPresence(UserState.OFFLINE, null); } catch (IOException e) { /* do nothing */ } } state = ConnectionState.DISCONNECTING; thread.closeSocket(); // this may result in a call to this method again! thread = null; state = ConnectionState.OFFLINE; for (Iterator it = getRoster().getContacts().iterator(); it.hasNext();) { ((Contact) it.next()).clear(); } notifyObservers(null); } } public synchronized boolean isConnected() { if (state == ConnectionState.ONLINE) { // check if really still online if (!thread.isConnected()) { disconnect(); return false; } return true; } return false; } public void setUserState(UserState newState, String text) { if (newState == UserState.OFFLINE) { disconnect(); } else { userState = newState; if (!isConnected()) { connect(); } else { try { thread.getOutput().sendPresence(userState, text); notifyObservers(null); } catch (IOException e) { disconnect(); } } } } public UserState getUserState() { if (userState == UserState.OFFLINE || userState == null) { userState = UserState.ONLINE; } return isConnected() ? userState : UserState.OFFLINE; } public void sendMessage(Message msg) { msg.setFrom(jid); try { thread.getOutput().sendMessage(msg); } catch (IOException e) { disconnect(); } } public Roster getRoster() { return roster; } ConnectionState getState() { return state; } public Jid getJid() { return jid; } protected void notifyObservers(Message msg) { super.notifyObservers(msg); } XMPPWriter getOutput() { return thread.getOutput(); } void setReader(ContentHandler handler) { thread.setReader(handler); } }