package de.uni_passau.fim.pkjab.model;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
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.Connection;
import de.uni_passau.fim.pkjab.model.SaslCallbackHandler;
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.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;
/* ======================================= callback methods for XMPPReader ====
* any exceptions thrown here end up wrapped in a SAXException and thrown by
* XMLReader.parse(), so they are caught in ConnectionThread.run()
*/
public class ConnectionCallback {
public final Connection connection;
ConnectionCallback(Connection connection) {
this.connection = connection;
}
public void setResource(String resource) {
connection.jid = new Jid(connection.jid.getUser(), connection.jid.getDomain(), resource);
}
public synchronized void setXMPPReader(final ContentHandler handler) {
System.out.println("Activating handler " + handler.getClass().getSimpleName());
connection.setReader(handler);
}
public synchronized XMPPAuthHandler firstInitWasSuccessful(Set features, Set saslMechanisms) throws IOException {
System.out.println("firstInitWasSuccessful");
if (features != null) {
System.out.println("Supported features: " + features);
}
if (connection.state != ConnectionState.DISCONNECTING) {
// Step 1: TLS would be here
// Step 2: Authenticate
if (saslMechanisms == null) {
System.err.println("Server does not support SASL authentification mechanisms!");
connection.disconnect();
return null;
} else {
System.out.println("Supported SASL mechanisms: " + saslMechanisms);
connection.state = ConnectionState.AUTHENTICATING;
SaslClient sasl = Sasl.createSaslClient((String[])saslMechanisms.toArray(new String[0]),
null, "xmpp", connection.getJid().getDomain(), null, new SaslCallbackHandler(connection));
if (sasl == null) {
System.err.println("No SASL provider found!");
connection.disconnect();
return null;
}
connection.getOutput().sendAuthInit(sasl.getMechanismName(),
sasl.hasInitialResponse() ? sasl.evaluateChallenge(new byte[0]) : null);
return new XMPPAuthHandler(sasl, connection.getOutput());
}
}
return null;
}
public synchronized void secondInitWasSuccessful(Set features) throws IOException {
System.out.println("secondInitWasSuccessful");
if (features != null) {
System.out.println("Supported features: " + features);
}
if (connection.state != ConnectionState.DISCONNECTING) {
connection.getOutput().sendBind(connection.getJid().getResource());
connection.getOutput().sendSessionInit();
connection.getOutput().sendPresence(connection.getUserState(), null);
}
}
public synchronized void handleQuery(Iq iq) throws IOException {
if (iq.getChild() != null) {
if (iq.type.equals("result")) {
if (iq.getChild().getName().equals("bind")) {
System.out.println("handleQuery: Bind ok");
} else if (iq.getChild().getName().equals("session")) {
System.out.println("handleQuery: Session establishment ok");
connection.state = ConnectionState.ONLINE;
connection.notifyObservers(null);
} else {
System.err.println("handleQuery: Result-Query with unknown child: " + iq.getChild());
}
} else {
System.err.println("handleQuery: " + iq.type + "-Query with unknown child: " + iq.getChild());
}
} else {
System.err.println("handleQuery: " + iq.type + "-Query without child");
}
}
}