diff --git a/source/org/jivesoftware/smack/XMPPConnection.java b/source/org/jivesoftware/smack/XMPPConnection.java
index 710aa9652..f467dadc2 100644
--- a/source/org/jivesoftware/smack/XMPPConnection.java
+++ b/source/org/jivesoftware/smack/XMPPConnection.java
@@ -54,6 +54,7 @@ package org.jivesoftware.smack;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.filter.*;
+import org.jivesoftware.smack.util.StringUtils;
import javax.swing.*;
import java.net.*;
@@ -111,10 +112,10 @@ public class XMPPConnection {
protected Socket socket;
String connectionID;
- private String username = null;
- private String resource = null;
+ private String user = null;
private boolean connected = false;
private boolean authenticated = false;
+ private boolean anonymous = false;
private PacketWriter packetWriter;
private PacketReader packetReader;
@@ -196,28 +197,17 @@ public class XMPPConnection {
}
/**
- * Returns the username that was used to login or null if not logged in yet.
+ * Returns the full XMPP address of the user that is logged in to the connection or
+ * null if not logged in yet. An XMPP address is in the form
+ * username@server/resource.
*
- * @return the username used to login.
+ * @return the full XMPP address of the user logged in.
*/
- public String getUsername() {
+ public String getUser() {
if (!isAuthenticated()) {
return null;
}
- return username;
- }
-
- /**
- * Returns the resource that was used to login or null if not logged in yet.
- * If no resource was used to login, the default resource "Smack" will be returned.
- *
- * @return the resource used to login.
- */
- public String getResource() {
- if (!isAuthenticated()) {
- return null;
- }
- return resource;
+ return user;
}
/**
@@ -256,8 +246,6 @@ public class XMPPConnection {
if (authenticated) {
throw new IllegalStateException("Already logged in to server.");
}
- this.username = username;
- this.resource = resource;
// If we send an authentication packet in "get" mode with just the username,
// the server will return the list of authentication protocols it supports.
Authentication discoveryAuth = new Authentication();
@@ -310,6 +298,17 @@ public class XMPPConnection {
else if (response.getType() == IQ.Type.ERROR) {
throw new XMPPException(response.getError());
}
+ // Set the user.
+ if (response.getTo() != null) {
+ this.user = response.getTo();
+ }
+ else {
+ Authentication authResponse = (Authentication)response;
+ this.user = authResponse.getUsername() + "@" + this.host;
+ if (authResponse.getResource() != null) {
+ this.user += "/" + authResponse.getResource();
+ }
+ }
// We're done with the collector, so explicitly cancel it.
collector.cancel();
@@ -322,6 +321,7 @@ public class XMPPConnection {
// Indicate that we're now authenticated.
authenticated = true;
+ anonymous = false;
// If debugging is enabled, change the the debug window title to include the
// name we are now logged-in as.
@@ -334,9 +334,72 @@ public class XMPPConnection {
}
}
+ /**
+ * Logs in to the server anonymously. Very few servers are configured to support anonymous
+ * authentication, so it's fairly likely logging in anonymously will fail. If anonymous login
+ * does succeed, your XMPP address will likely be in the form "server/123ABC" (where "123ABC" is a
+ * random value generated by the server).
+ *
+ * @throws XMPPException if an error occurs or anonymous logins are not supported by the server.
+ * @throws IllegalStateException if not connected to the server, or already logged in
+ * to the serrver.
+ */
+ public synchronized void loginAnonymously() throws XMPPException {
+ if (!isConnected()) {
+ throw new IllegalStateException("Not connected to server.");
+ }
+ if (authenticated) {
+ throw new IllegalStateException("Already logged in to server.");
+ }
+
+ // Create the authentication packet we'll send to the server.
+ Authentication auth = new Authentication();
+
+ PacketCollector collector = packetReader.createPacketCollector(
+ new PacketIDFilter(auth.getPacketID()));
+ // Send the packet.
+ packetWriter.sendPacket(auth);
+ // Wait up to five seconds for a response from the server.
+ IQ response = (IQ)collector.nextResult(5000);
+ if (response == null) {
+ throw new XMPPException("Anonymous login failed.");
+ }
+ else if (response.getType() == IQ.Type.ERROR) {
+ throw new XMPPException(response.getError());
+ }
+ // Set the user value.
+ if (response.getTo() != null) {
+ this.user = response.getTo();
+ }
+ else {
+ this.user = this.host + "/" + ((Authentication)response).getResource();
+ }
+ // We're done with the collector, so explicitly cancel it.
+ collector.cancel();
+
+ // Anonymous users can't have a roster.
+ roster = null;
+
+ // Set presence to online.
+ packetWriter.sendPacket(new Presence(Presence.Type.AVAILABLE));
+
+ // Indicate that we're now authenticated.
+ authenticated = true;
+ anonymous = true;
+
+ // If debugging is enabled, change the the debug window title to include the
+ // name we are now logged-in as.
+ if (DEBUG_ENABLED) {
+ String title = "Smack Debug Window -- " + getHost() + ":" + getPort();
+ title += "/" + StringUtils.parseResource(user);
+ debugFrame.setTitle(title);
+ }
+ }
+
/**
* Returns the roster for the user logged into the server. If the user has not yet
- * logged into the server, this method will return null.
+ * logged into the server (or if the user is logged in anonymously), this method will return
+ * null.
*
* @return the user's roster, or null if the user has not logged in yet.
*/
@@ -421,6 +484,15 @@ public class XMPPConnection {
return authenticated;
}
+ /**
+ * Returns true if currently authenticated anonymously.
+ *
+ * @return true if authenticated anonymously.
+ */
+ public boolean isAnonymous() {
+ return anonymous;
+ }
+
/**
* Closes the connection by setting presence to unavailable then closing the stream to
* the XMPP server. Once a connection has been closed, it cannot be re-opened.