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);
}
}