1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-25 13:32:07 +01:00

Use Jid (and subclasses) from jxmpp-jid

Fixes SMACK-634
This commit is contained in:
Florian Schmaus 2015-02-14 17:15:02 +01:00
parent 0ee2d9ed1e
commit 5bb4727c57
180 changed files with 1510 additions and 1032 deletions

View file

@ -43,6 +43,7 @@ import org.jivesoftware.smack.packet.Presence.Type;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success;
import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.PacketParserUtils;
import org.jxmpp.jid.DomainBareJid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParserFactory;
import org.igniterealtime.jbosh.AbstractBody; import org.igniterealtime.jbosh.AbstractBody;
@ -116,7 +117,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
* @param xmppDomain the XMPP service name * @param xmppDomain the XMPP service name
* (e.g. domain.lt for the user alice@domain.lt) * (e.g. domain.lt for the user alice@domain.lt)
*/ */
public XMPPBOSHConnection(String username, String password, boolean https, String host, int port, String filePath, String xmppDomain) { public XMPPBOSHConnection(String username, String password, boolean https, String host, int port, String filePath, DomainBareJid xmppDomain) {
this(BOSHConfiguration.builder().setUseHttps(https).setHost(host) this(BOSHConfiguration.builder().setUseHttps(https).setHost(host)
.setPort(port).setFile(filePath).setServiceName(xmppDomain) .setPort(port).setFile(filePath).setServiceName(xmppDomain)
.setUsernameAndPassword(username, password).build()); .setUsernameAndPassword(username, password).build());
@ -145,7 +146,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
// Initialize BOSH client // Initialize BOSH client
BOSHClientConfig.Builder cfgBuilder = BOSHClientConfig.Builder BOSHClientConfig.Builder cfgBuilder = BOSHClientConfig.Builder
.create(config.getURI(), config.getServiceName()); .create(config.getURI(), config.getServiceName().toString());
if (config.isProxyEnabled()) { if (config.isProxyEnabled()) {
cfgBuilder.setProxy(config.getProxyAddress(), config.getProxyPort()); cfgBuilder.setProxy(config.getProxyAddress(), config.getProxyPort());
} }
@ -537,7 +538,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
XMPPBOSHConnection.XMPP_BOSH_NS).setAttribute( XMPPBOSHConnection.XMPP_BOSH_NS).setAttribute(
BodyQName.createWithPrefix(XMPPBOSHConnection.XMPP_BOSH_NS, "restart", BodyQName.createWithPrefix(XMPPBOSHConnection.XMPP_BOSH_NS, "restart",
"xmpp"), "true").setAttribute( "xmpp"), "true").setAttribute(
BodyQName.create(XMPPBOSHConnection.BOSH_URI, "to"), getServiceName()).build()); BodyQName.create(XMPPBOSHConnection.BOSH_URI, "to"), getServiceName().toString()).build());
Success success = new Success(parser.nextText()); Success success = new Success(parser.nextText());
getSASLAuthentication().authenticated(success); getSASLAuthentication().authenticated(success);
break; break;

View file

@ -9,7 +9,8 @@ Smack core components."""
dependencies { dependencies {
compile 'xpp3:xpp3:1.1.4c' compile 'xpp3:xpp3:1.1.4c'
compile "org.jxmpp:jxmpp-core:$jxmppVersion" compile "org.jxmpp:jxmpp-core:$jxmppVersion"
// compile "org.igniterealtime.jxmpp:jxmpp-jid:$jxmppVersion" compile "org.jxmpp:jxmpp-jid:$jxmppVersion"
testCompile "org.jxmpp:jxmpp-jid:$jxmppVersion:tests"
testCompile 'junit:junit:4.11' testCompile 'junit:junit:4.11'
testCompile 'xmlunit:xmlunit:1.5' testCompile 'xmlunit:xmlunit:1.5'
testCompile 'org.powermock:powermock-module-junit4:1.5.5' testCompile 'org.powermock:powermock-module-junit4:1.5.5'

View file

@ -81,6 +81,9 @@ import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.util.SmackExecutorThreadFactory; import org.jivesoftware.smack.util.SmackExecutorThreadFactory;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.dns.HostAddress; import org.jivesoftware.smack.util.dns.HostAddress;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.util.XmppStringUtils;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -164,7 +167,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
* certificate. * certificate.
* </p> * </p>
*/ */
protected String user; protected FullJid user;
protected boolean connected = false; protected boolean connected = false;
@ -342,7 +345,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
} }
@Override @Override
public String getServiceName() { public DomainBareJid getServiceName() {
if (serviceName != null) { if (serviceName != null) {
return serviceName; return serviceName;
} }
@ -510,7 +513,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
} }
@Override @Override
public final String getUser() { public final FullJid getUser() {
return user; return user;
} }
@ -550,7 +553,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
// from the login() arguments and the configurations service name, as, for example, when SASL External is used, // from the login() arguments and the configurations service name, as, for example, when SASL External is used,
// the username is not given to login but taken from the 'external' certificate. // the username is not given to login but taken from the 'external' certificate.
user = response.getJid(); user = response.getJid();
serviceName = XmppStringUtils.parseDomain(user); serviceName = user.asDomainBareJid();
Session.Feature sessionFeature = getFeature(Session.ELEMENT, Session.NAMESPACE); Session.Feature sessionFeature = getFeature(Session.ELEMENT, Session.NAMESPACE);
// Only bind the session if it's announced as stream feature by the server, is not optional and not disabled // Only bind the session if it's announced as stream feature by the server, is not optional and not disabled
@ -590,7 +593,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
&& !config.allowNullOrEmptyUsername; && !config.allowNullOrEmptyUsername;
} }
private String serviceName; private DomainBareJid serviceName;
protected List<HostAddress> hostAddresses; protected List<HostAddress> hostAddresses;
@ -608,7 +611,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
hostAddress = new HostAddress(config.host, config.port); hostAddress = new HostAddress(config.host, config.port);
hostAddresses.add(hostAddress); hostAddresses.add(hostAddress);
} else { } else {
hostAddresses = DNSUtil.resolveXMPPDomain(config.serviceName, failedAddresses); hostAddresses = DNSUtil.resolveXMPPDomain(config.serviceName.toString(), failedAddresses);
} }
// If we reach this, then hostAddresses *must not* be empty, i.e. there is at least one host added, either the // If we reach this, then hostAddresses *must not* be empty, i.e. there is at least one host added, either the
// config.host one or the host representing the service name by DNSUtil // config.host one or the host representing the service name by DNSUtil
@ -645,7 +648,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
throwNotConnectedExceptionIfAppropriate(); throwNotConnectedExceptionIfAppropriate();
switch (fromMode) { switch (fromMode) {
case OMITTED: case OMITTED:
packet.setFrom(null); packet.setFrom((Jid) null);
break; break;
case USER: case USER:
packet.setFrom(getUser()); packet.setFrom(getUser());

View file

@ -19,6 +19,7 @@ package org.jivesoftware.smack;
import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.proxy.ProxyInfo; import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jxmpp.jid.DomainBareJid;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
@ -43,7 +44,7 @@ public abstract class ConnectionConfiguration {
* of the server. However, there are some servers like google where host would be * of the server. However, there are some servers like google where host would be
* talk.google.com and the serviceName would be gmail.com. * talk.google.com and the serviceName would be gmail.com.
*/ */
protected final String serviceName; protected final DomainBareJid serviceName;
protected final String host; protected final String host;
protected final int port; protected final int port;
@ -136,7 +137,7 @@ public abstract class ConnectionConfiguration {
* *
* @return the server name of the target server. * @return the server name of the target server.
*/ */
public String getServiceName() { public DomainBareJid getServiceName() {
return serviceName; return serviceName;
} }
@ -382,7 +383,7 @@ public abstract class ConnectionConfiguration {
private CallbackHandler callbackHandler; private CallbackHandler callbackHandler;
private boolean debuggerEnabled = SmackConfiguration.DEBUG; private boolean debuggerEnabled = SmackConfiguration.DEBUG;
private SocketFactory socketFactory; private SocketFactory socketFactory;
private String serviceName; private DomainBareJid serviceName;
private String host; private String host;
private int port = 5222; private int port = 5222;
private boolean allowEmptyOrNullUsername = false; private boolean allowEmptyOrNullUsername = false;
@ -413,7 +414,7 @@ public abstract class ConnectionConfiguration {
* @param serviceName the service name * @param serviceName the service name
* @return a reference to this builder. * @return a reference to this builder.
*/ */
public B setServiceName(String serviceName) { public B setServiceName(DomainBareJid serviceName) {
this.serviceName = serviceName; this.serviceName = serviceName;
return getThis(); return getThis();
} }

View file

@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.util.dns.HostAddress; import org.jivesoftware.smack.util.dns.HostAddress;
import org.jxmpp.jid.Jid;
/** /**
* Smack uses SmackExceptions for errors that are not defined by any XMPP specification. * Smack uses SmackExceptions for errors that are not defined by any XMPP specification.
@ -225,13 +226,13 @@ public class SmackException extends Exception {
private static final long serialVersionUID = 4713404802621452016L; private static final long serialVersionUID = 4713404802621452016L;
private final String feature; private final String feature;
private final String jid; private final Jid jid;
public FeatureNotSupportedException(String feature) { public FeatureNotSupportedException(String feature) {
this(feature, null); this(feature, null);
} }
public FeatureNotSupportedException(String feature, String jid) { public FeatureNotSupportedException(String feature, Jid jid) {
super(feature + " not supported" + (jid == null ? "" : " by '" + jid + "'")); super(feature + " not supported" + (jid == null ? "" : " by '" + jid + "'"));
this.jid = jid; this.jid = jid;
this.feature = feature; this.feature = feature;
@ -252,7 +253,7 @@ public class SmackException extends Exception {
* *
* @return the JID which does not support the feature, or null * @return the JID which does not support the feature, or null
*/ */
public String getJid() { public Jid getJid() {
return jid; return jid;
} }
} }

View file

@ -26,6 +26,8 @@ import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.packet.PlainStreamElement; import org.jivesoftware.smack.packet.PlainStreamElement;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.FullJid;
/** /**
* The XMPPConnection interface provides an interface for connections to an XMPP server and * The XMPPConnection interface provides an interface for connections to an XMPP server and
@ -78,7 +80,7 @@ public interface XMPPConnection {
* *
* @return the name of the service provided by the XMPP server. * @return the name of the service provided by the XMPP server.
*/ */
public String getServiceName(); public DomainBareJid getServiceName();
/** /**
* Returns the host name of the server where the XMPP server is running. This would be the * Returns the host name of the server where the XMPP server is running. This would be the
@ -103,7 +105,7 @@ public interface XMPPConnection {
* *
* @return the full XMPP address of the user logged in. * @return the full XMPP address of the user logged in.
*/ */
public String getUser(); public FullJid getUser();
/** /**
* Returns the stream ID for this connection, which is the value set by the server * Returns the stream ID for this connection, which is the value set by the server

View file

@ -24,7 +24,7 @@ import org.jivesoftware.smack.util.ObservableReader;
import org.jivesoftware.smack.util.ObservableWriter; import org.jivesoftware.smack.util.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener; import org.jivesoftware.smack.util.ReaderListener;
import org.jivesoftware.smack.util.WriterListener; import org.jivesoftware.smack.util.WriterListener;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.FullJid;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
@ -141,8 +141,9 @@ public abstract class AbstractDebugger implements SmackDebugger {
return writer; return writer;
} }
public void userHasLogged(String user) { @Override
String localpart = XmppStringUtils.parseLocalpart(user); public void userHasLogged(FullJid user) {
String localpart = user.getLocalpart().toString();
boolean isAnonymous = "".equals(localpart); boolean isAnonymous = "".equals(localpart);
String title = String title =
"User logged (" + connection.getConnectionCounter() + "): " "User logged (" + connection.getConnectionCounter() + "): "
@ -151,7 +152,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
+ connection.getServiceName() + connection.getServiceName()
+ ":" + ":"
+ connection.getPort(); + connection.getPort();
title += "/" + XmppStringUtils.parseResource(user); title += "/" + user.getResourcepart();
log(title); log(title);
// Add the connection listener to the connection so that the debugger can be notified // Add the connection listener to the connection so that the debugger can be notified
// whenever the connection is closed. // whenever the connection is closed.

View file

@ -21,6 +21,7 @@ import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import org.jivesoftware.smack.PacketListener; import org.jivesoftware.smack.PacketListener;
import org.jxmpp.jid.FullJid;
/** /**
* Interface that allows for implementing classes to debug XML traffic. That is a GUI window that * Interface that allows for implementing classes to debug XML traffic. That is a GUI window that
@ -40,7 +41,7 @@ public interface SmackDebugger {
* *
* @param user the user@host/resource that has just logged in * @param user the user@host/resource that has just logged in
*/ */
public abstract void userHasLogged(String user); public abstract void userHasLogged(FullJid user);
/** /**
* Returns the special Reader that wraps the main Reader and logs data to the GUI. * Returns the special Reader that wraps the main Reader and logs data to the GUI.

View file

@ -17,10 +17,8 @@
package org.jivesoftware.smack.filter; package org.jivesoftware.smack.filter;
import java.util.Locale;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.Jid;
/** /**
* Filter for packets where the "from" field exactly matches a specified JID. If the specified * Filter for packets where the "from" field exactly matches a specified JID. If the specified
@ -32,12 +30,12 @@ import org.jxmpp.util.XmppStringUtils;
*/ */
public class FromMatchesFilter implements PacketFilter { public class FromMatchesFilter implements PacketFilter {
private final String address; private final Jid address;
/** /**
* Flag that indicates if the checking will be done against bare JID addresses or full JIDs. * Flag that indicates if the checking will be done against bare JID addresses or full JIDs.
*/ */
private final boolean matchBareJID; private final boolean ignoreResourcepart;
/** /**
* Creates a filter matching on the "from" field. The from address must be the same as the * Creates a filter matching on the "from" field. The from address must be the same as the
@ -46,11 +44,16 @@ public class FromMatchesFilter implements PacketFilter {
* *
* @param address The address to filter for. If <code>null</code> is given, the packet must not * @param address The address to filter for. If <code>null</code> is given, the packet must not
* have a from address. * have a from address.
* @param matchBare * @param ignoreResourcepart
*/ */
public FromMatchesFilter(String address, boolean matchBare) { public FromMatchesFilter(Jid address, boolean ignoreResourcepart) {
this.address = (address == null) ? null : address.toLowerCase(Locale.US); if (address != null && ignoreResourcepart) {
matchBareJID = matchBare; this.address = address.withoutResource();
}
else {
this.address = address;
}
this.ignoreResourcepart = ignoreResourcepart;
} }
/** /**
@ -61,8 +64,8 @@ public class FromMatchesFilter implements PacketFilter {
* @param address The address to filter for. If <code>null</code> is given, the packet must not * @param address The address to filter for. If <code>null</code> is given, the packet must not
* have a from address. * have a from address.
*/ */
public static FromMatchesFilter create(String address) { public static FromMatchesFilter create(Jid address) {
return new FromMatchesFilter(address, "".equals(XmppStringUtils.parseResource(address))) ; return new FromMatchesFilter(address, address.hasNoResource()) ;
} }
/** /**
@ -72,8 +75,8 @@ public class FromMatchesFilter implements PacketFilter {
* @param address The address to filter for. If <code>null</code> is given, the packet must not * @param address The address to filter for. If <code>null</code> is given, the packet must not
* have a from address. * have a from address.
*/ */
public static FromMatchesFilter createBare(String address) { public static FromMatchesFilter createBare(Jid address) {
address = (address == null) ? null : XmppStringUtils.parseBareJid(address); address = (address == null) ? null : address;
return new FromMatchesFilter(address, true); return new FromMatchesFilter(address, true);
} }
@ -85,25 +88,24 @@ public class FromMatchesFilter implements PacketFilter {
* @param address The address to filter for. If <code>null</code> is given, the packet must not * @param address The address to filter for. If <code>null</code> is given, the packet must not
* have a from address. * have a from address.
*/ */
public static FromMatchesFilter createFull(String address) { public static FromMatchesFilter createFull(Jid address) {
return new FromMatchesFilter(address, false); return new FromMatchesFilter(address, false);
} }
public boolean accept(Stanza packet) { public boolean accept(Stanza packet) {
String from = packet.getFrom(); Jid from = packet.getFrom();
if (from == null) { if (from == null) {
return address == null; return address == null;
} }
// Simplest form of NAMEPREP/STRINGPREP
from = from.toLowerCase(Locale.US); if (ignoreResourcepart) {
if (matchBareJID) { from = from.withoutResource();
from = XmppStringUtils.parseBareJid(from);
} }
return from.equals(address); return from.equals(address);
} }
public String toString() { public String toString() {
String matchMode = matchBareJID ? "bare" : "full"; String matchMode = ignoreResourcepart ? "ignoreResourcepart" : "full";
return "FromMatchesFilter (" +matchMode + "): " + address; return "FromMatchesFilter (" +matchMode + "): " + address;
} }
} }

View file

@ -16,14 +16,15 @@
*/ */
package org.jivesoftware.smack.filter; package org.jivesoftware.smack.filter;
import java.util.Locale;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
/** /**
* Filters for packets which are a valid reply to an IQ request. * Filters for packets which are a valid reply to an IQ request.
@ -53,9 +54,9 @@ public class IQReplyFilter implements PacketFilter {
private final PacketFilter iqAndIdFilter; private final PacketFilter iqAndIdFilter;
private final OrFilter fromFilter; private final OrFilter fromFilter;
private final String to; private final Jid to;
private final String local; private final FullJid local;
private final String server; private final DomainBareJid server;
private final String packetId; private final String packetId;
/** /**
@ -84,18 +85,13 @@ public class IQReplyFilter implements PacketFilter {
if (!iqPacket.isRequestIQ()) { if (!iqPacket.isRequestIQ()) {
throw new IllegalArgumentException("IQ must be a request IQ, i.e. of type 'get' or 'set'."); throw new IllegalArgumentException("IQ must be a request IQ, i.e. of type 'get' or 'set'.");
} }
if (iqPacket.getTo() != null) { to = iqPacket.getTo();
to = iqPacket.getTo().toLowerCase(Locale.US); local = conn.getUser();
} else { if (local == null) {
to = null;
}
final String localJid = conn.getUser();
if (localJid == null) {
throw new IllegalArgumentException("Must have a local (user) JID set. Either you didn't configure one or you where not connected at least once"); throw new IllegalArgumentException("Must have a local (user) JID set. Either you didn't configure one or you where not connected at least once");
} }
local = localJid.toLowerCase(Locale.US);
server = conn.getServiceName().toLowerCase(Locale.US); server = conn.getServiceName();
packetId = iqPacket.getStanzaId(); packetId = iqPacket.getStanzaId();
PacketFilter iqFilter = new OrFilter(IQTypeFilter.ERROR, IQTypeFilter.RESULT); PacketFilter iqFilter = new OrFilter(IQTypeFilter.ERROR, IQTypeFilter.RESULT);
@ -107,7 +103,7 @@ public class IQReplyFilter implements PacketFilter {
fromFilter.addFilter(FromMatchesFilter.createBare(local)); fromFilter.addFilter(FromMatchesFilter.createBare(local));
fromFilter.addFilter(FromMatchesFilter.createFull(server)); fromFilter.addFilter(FromMatchesFilter.createFull(server));
} }
else if (to.equals(XmppStringUtils.parseBareJid(local))) { else if (to.equals(local.asBareJid())) {
fromFilter.addFilter(FromMatchesFilter.createFull(null)); fromFilter.addFilter(FromMatchesFilter.createFull(null));
} }
} }

View file

@ -16,25 +16,23 @@
*/ */
package org.jivesoftware.smack.filter; package org.jivesoftware.smack.filter;
import java.util.Locale;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jxmpp.jid.Jid;
public class ToFilter implements PacketFilter { public class ToFilter implements PacketFilter {
private final String to; private final Jid to;
public ToFilter(String to) { public ToFilter(Jid to) {
this.to = to.toLowerCase(Locale.US); this.to = to;
} }
@Override @Override
public boolean accept(Stanza packet) { public boolean accept(Stanza packet) {
String packetTo = packet.getTo(); Jid packetTo = packet.getTo();
if (packetTo == null) { if (packetTo == null) {
return false; return false;
} }
packetTo = packetTo.toLowerCase(Locale.US);
return packetTo.equals(to); return packetTo.equals(to);
} }

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smack.packet; package org.jivesoftware.smack.packet;
import org.jxmpp.jid.FullJid;
/** /**
* IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server. * IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server.
* There are two ways to bind a resource. One is simply sending an empty Bind packet where the * There are two ways to bind a resource. One is simply sending an empty Bind packet where the
@ -34,9 +36,9 @@ public class Bind extends IQ {
public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-bind"; public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-bind";
private final String resource; private final String resource;
private final String jid; private final FullJid jid;
public Bind(String resource, String jid) { public Bind(String resource, FullJid jid) {
super(ELEMENT, NAMESPACE); super(ELEMENT, NAMESPACE);
this.resource = resource; this.resource = resource;
this.jid = jid; this.jid = jid;
@ -46,7 +48,7 @@ public class Bind extends IQ {
return resource; return resource;
} }
public String getJid() { public FullJid getJid() {
return jid; return jid;
} }
@ -56,7 +58,7 @@ public class Bind extends IQ {
return bind; return bind;
} }
public static Bind newResult(String jid) { public static Bind newResult(FullJid jid) {
return new Bind(null, jid); return new Bind(null, jid);
} }

View file

@ -25,6 +25,7 @@ import java.util.Locale;
import java.util.Set; import java.util.Set;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
/** /**
* Represents XMPP message packets. A message can be one of several types: * Represents XMPP message packets. A message can be one of several types:
@ -72,7 +73,7 @@ public final class Message extends Stanza {
* *
* @param to the recipient of the message. * @param to the recipient of the message.
*/ */
public Message(String to) { public Message(Jid to) {
setTo(to); setTo(to);
} }
@ -82,7 +83,7 @@ public final class Message extends Stanza {
* @param to the user to send the message to. * @param to the user to send the message to.
* @param type the message type. * @param type the message type.
*/ */
public Message(String to, Type type) { public Message(Jid to, Type type) {
this(to); this(to);
setType(type); setType(type);
} }
@ -93,7 +94,7 @@ public final class Message extends Stanza {
* @param to the user to send the message to. * @param to the user to send the message to.
* @param body the body of the message. * @param body the body of the message.
*/ */
public Message(String to, String body) { public Message(Jid to, String body) {
this(to); this(to);
setBody(body); setBody(body);
} }

View file

@ -23,6 +23,9 @@ import org.jivesoftware.smack.packet.id.StanzaIdUtil;
import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smack.util.PacketUtil; import org.jivesoftware.smack.util.PacketUtil;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.util.XmppStringUtils;
import java.util.Collection; import java.util.Collection;
@ -56,8 +59,8 @@ public abstract class Stanza implements TopLevelStreamElement {
private final MultiMap<String, PacketExtension> packetExtensions = new MultiMap<>(); private final MultiMap<String, PacketExtension> packetExtensions = new MultiMap<>();
private String id = null; private String id = null;
private String to = null; private Jid to;
private String from = null; private Jid from;
private XMPPError error = null; private XMPPError error = null;
/** /**
@ -154,7 +157,7 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return who the packet is being sent to, or <tt>null</tt> if the * @return who the packet is being sent to, or <tt>null</tt> if the
* value has not been set. * value has not been set.
*/ */
public String getTo() { public Jid getTo() {
return to; return to;
} }
@ -163,8 +166,28 @@ public abstract class Stanza implements TopLevelStreamElement {
* the "to" attribute optional, so it does not always need to be set. * the "to" attribute optional, so it does not always need to be set.
* *
* @param to who the packet is being sent to. * @param to who the packet is being sent to.
* @throws IllegalArgumentException if to is not a valid JID String.
* @deprecated use {@link #setTo(Jid)} instead.
*/ */
@Deprecated
public void setTo(String to) { public void setTo(String to) {
Jid jid;
try {
jid = JidCreate.from(to);
}
catch (XmppStringprepException e) {
throw new IllegalArgumentException(e);
}
setTo(jid);
}
/**
* Sets who the packet is being sent "to". The XMPP protocol often makes
* the "to" attribute optional, so it does not always need to be set.
*
* @param to who the packet is being sent to.
*/
public void setTo(Jid to) {
this.to = to; this.to = to;
} }
@ -176,7 +199,7 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return who the packet is being sent from, or <tt>null</tt> if the * @return who the packet is being sent from, or <tt>null</tt> if the
* value has not been set. * value has not been set.
*/ */
public String getFrom() { public Jid getFrom() {
return from; return from;
} }
@ -186,8 +209,29 @@ public abstract class Stanza implements TopLevelStreamElement {
* be set. * be set.
* *
* @param from who the packet is being sent to. * @param from who the packet is being sent to.
* @throws IllegalArgumentException if from is not a valid JID String.
* @deprecated use {@link #setFrom(Jid)} instead.
*/ */
@Deprecated
public void setFrom(String from) { public void setFrom(String from) {
Jid jid;
try {
jid = JidCreate.from(from);
}
catch (XmppStringprepException e) {
throw new IllegalArgumentException(e);
}
setFrom(jid);
}
/**
* Sets who the packet is being sent "from". The XMPP protocol often
* makes the "from" attribute optional, so it does not always need to
* be set.
*
* @param from who the packet is being sent to.
*/
public void setFrom(Jid from) {
this.from = from; this.from = from;
} }

View file

@ -20,6 +20,8 @@ import java.io.IOException;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.Bind; import org.jivesoftware.smack.packet.Bind;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.impl.JidCreate;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -40,7 +42,8 @@ public class BindIQProvider extends IQProvider<Bind> {
bind = Bind.newSet(parser.nextText()); bind = Bind.newSet(parser.nextText());
break; break;
case "jid": case "jid":
bind = Bind.newResult(parser.nextText()); FullJid fullJid = JidCreate.fullFrom(parser.nextText());
bind = Bind.newResult(fullJid);
break; break;
} }
break; break;

View file

@ -24,6 +24,7 @@ import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Response;
import org.jivesoftware.smack.util.StringTransformer; import org.jivesoftware.smack.util.StringTransformer;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jxmpp.jid.DomainBareJid;
import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.CallbackHandler;
@ -33,9 +34,9 @@ import javax.security.auth.callback.CallbackHandler;
* <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li> * <li>{@link #getName()} -- returns the common name of the SASL mechanism.</li>
* </ul> * </ul>
* Subclasses will likely want to implement their own versions of these methods: * Subclasses will likely want to implement their own versions of these methods:
* <li>{@link #authenticate(String, String, String, String)} -- Initiate authentication stanza using the * <li>{@link #authenticate(String, String, DomainBareJid, String)} -- Initiate authentication stanza using the
* deprecated method.</li> * deprecated method.</li>
* <li>{@link #authenticate(String, String, CallbackHandler)} -- Initiate authentication stanza * <li>{@link #authenticate(String, DomainBareJid, CallbackHandler)} -- Initiate authentication stanza
* using the CallbackHandler method.</li> * using the CallbackHandler method.</li>
* <li>{@link #challengeReceived(String, boolean)} -- Handle a challenge from the server.</li> * <li>{@link #challengeReceived(String, boolean)} -- Handle a challenge from the server.</li>
* </ul> * </ul>
@ -104,7 +105,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
/** /**
* The name of the XMPP service * The name of the XMPP service
*/ */
protected String serviceName; protected DomainBareJid serviceName;
/** /**
* The users password * The users password
@ -115,7 +116,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
/** /**
* Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of * Builds and sends the <tt>auth</tt> stanza to the server. Note that this method of
* authentication is not recommended, since it is very inflexible. Use * authentication is not recommended, since it is very inflexible. Use
* {@link #authenticate(String, String, CallbackHandler)} whenever possible. * {@link #authenticate(String, DomainBareJid, CallbackHandler)} whenever possible.
* *
* Explanation of auth stanza: * Explanation of auth stanza:
* *
@ -160,7 +161,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public final void authenticate(String username, String host, String serviceName, String password) public final void authenticate(String username, String host, DomainBareJid serviceName, String password)
throws SmackException, NotConnectedException, InterruptedException { throws SmackException, NotConnectedException, InterruptedException {
this.authenticationId = username; this.authenticationId = username;
this.host = host; this.host = host;
@ -184,7 +185,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void authenticate(String host,String serviceName, CallbackHandler cbh) public void authenticate(String host, DomainBareJid serviceName, CallbackHandler cbh)
throws SmackException, NotConnectedException, InterruptedException { throws SmackException, NotConnectedException, InterruptedException {
this.host = host; this.host = host;
this.serviceName = serviceName; this.serviceName = serviceName;

View file

@ -47,6 +47,7 @@ import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlPullParserFactory;
@ -222,8 +223,8 @@ public class PacketParserUtils {
final int initialDepth = parser.getDepth(); final int initialDepth = parser.getDepth();
Message message = new Message(); Message message = new Message();
message.setStanzaId(parser.getAttributeValue("", "id")); message.setStanzaId(parser.getAttributeValue("", "id"));
message.setTo(parser.getAttributeValue("", "to")); message.setTo(ParserUtils.getJidAttribute(parser, "to"));
message.setFrom(parser.getAttributeValue("", "from")); message.setFrom(ParserUtils.getJidAttribute(parser, "from"));
String typeString = parser.getAttributeValue("", "type"); String typeString = parser.getAttributeValue("", "type");
if (typeString != null) { if (typeString != null) {
message.setType(Message.Type.fromString(typeString)); message.setType(Message.Type.fromString(typeString));
@ -527,8 +528,8 @@ public class PacketParserUtils {
type = Presence.Type.fromString(typeString); type = Presence.Type.fromString(typeString);
} }
Presence presence = new Presence(type); Presence presence = new Presence(type);
presence.setTo(parser.getAttributeValue("", "to")); presence.setTo(ParserUtils.getJidAttribute(parser, "to"));
presence.setFrom(parser.getAttributeValue("", "from")); presence.setFrom(ParserUtils.getJidAttribute(parser, "from"));
presence.setStanzaId(parser.getAttributeValue("", "id")); presence.setStanzaId(parser.getAttributeValue("", "id"));
String language = getLanguageAttribute(parser); String language = getLanguageAttribute(parser);
@ -606,8 +607,8 @@ public class PacketParserUtils {
XMPPError error = null; XMPPError error = null;
final String id = parser.getAttributeValue("", "id"); final String id = parser.getAttributeValue("", "id");
final String to = parser.getAttributeValue("", "to"); final Jid to = ParserUtils.getJidAttribute(parser, "to");
final String from = parser.getAttributeValue("", "from"); final Jid from = ParserUtils.getJidAttribute(parser, "from");
final IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type")); final IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type"));
outerloop: while (true) { outerloop: while (true) {

View file

@ -19,6 +19,10 @@ package org.jivesoftware.smack.util;
import java.io.IOException; import java.io.IOException;
import java.util.Locale; import java.util.Locale;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -39,6 +43,26 @@ public class ParserUtils {
} }
} }
public static Jid getJidAttribute(XmlPullParser parser) throws XmppStringprepException {
return getJidAttribute(parser, "jid");
}
public static Jid getJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
final String jidString = parser.getAttributeValue("", name);
if (jidString == null) {
return null;
}
return JidCreate.from(jidString);
}
public static Resourcepart getResourcepartAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
final String resourcepartString = parser.getAttributeValue("", name);
if (resourcepartString == null) {
return null;
}
return Resourcepart.from(resourcepartString);
}
/** /**
* Get the boolean value of an argument. * Get the boolean value of an argument.
* *

View file

@ -63,6 +63,16 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
/**
*
* @param name
* @param content
* @return the XmlStringBuilder
*/
public XmlStringBuilder element(String name, CharSequence content) {
return element(name, content.toString());
}
public XmlStringBuilder element(String name, Enum<?> content) { public XmlStringBuilder element(String name, Enum<?> content) {
assert content != null; assert content != null;
element(name, content.name()); element(name, content.name());
@ -81,6 +91,13 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
public XmlStringBuilder optElement(String name, CharSequence content) {
if (content != null) {
element(name, content.toString());
}
return this;
}
public XmlStringBuilder optElement(Element element) { public XmlStringBuilder optElement(Element element) {
if (element != null) { if (element != null) {
append(element.toXML()); append(element.toXML());
@ -168,6 +185,10 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
public XmlStringBuilder attribute(String name, CharSequence value) {
return attribute(name, value.toString());
}
public XmlStringBuilder attribute(String name, Enum<?> value) { public XmlStringBuilder attribute(String name, Enum<?> value) {
assert value != null; assert value != null;
attribute(name, value.name()); attribute(name, value.name());
@ -186,6 +207,13 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
public XmlStringBuilder optAttribute(String name, CharSequence value) {
if (value != null) {
attribute(name, value.toString());
}
return this;
}
public XmlStringBuilder optAttribute(String name, Enum<?> value) { public XmlStringBuilder optAttribute(String name, Enum<?> value) {
if (value != null) { if (value != null) {
attribute(name, value.toString()); attribute(name, value.toString());
@ -244,6 +272,10 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this; return this;
} }
public XmlStringBuilder escape(CharSequence text) {
return escape(text.toString());
}
public XmlStringBuilder prelude(PacketExtension pe) { public XmlStringBuilder prelude(PacketExtension pe) {
return prelude(pe.getElementName(), pe.getNamespace()); return prelude(pe.getElementName(), pe.getNamespace());
} }

View file

@ -27,6 +27,10 @@ import java.util.concurrent.TimeUnit;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.PlainStreamElement; import org.jivesoftware.smack.packet.PlainStreamElement;
import org.jivesoftware.smack.packet.TopLevelStreamElement; import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.JidTestUtil;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
/** /**
* A dummy implementation of {@link XMPPConnection}, intended to be used during * A dummy implementation of {@link XMPPConnection}, intended to be used during
@ -51,7 +55,7 @@ public class DummyConnection extends AbstractXMPPConnection {
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>(); private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
public static ConnectionConfiguration.Builder<?,?> getDummyConfigurationBuilder() { public static ConnectionConfiguration.Builder<?,?> getDummyConfigurationBuilder() {
return DummyConnectionConfiguration.builder().setServiceName("example.org").setUsernameAndPassword("dummy", return DummyConnectionConfiguration.builder().setServiceName(JidTestUtil.EXAMPLE_ORG).setUsernameAndPassword("dummy",
"dummypass"); "dummypass");
} }
@ -59,17 +63,26 @@ public class DummyConnection extends AbstractXMPPConnection {
this(getDummyConfigurationBuilder().build()); this(getDummyConfigurationBuilder().build());
} }
private FullJid getUserJid() {
try {
return JidCreate.fullFrom(config.getUsername()
+ "@"
+ config.getServiceName()
+ "/"
+ (config.getResource() != null ? config.getResource() : "Test"));
}
catch (XmppStringprepException e) {
throw new IllegalStateException(e);
}
}
public DummyConnection(ConnectionConfiguration configuration) { public DummyConnection(ConnectionConfiguration configuration) {
super(configuration); super(configuration);
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) { for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
listener.connectionCreated(this); listener.connectionCreated(this);
} }
user = config.getUsername() user = getUserJid();
+ "@"
+ config.getServiceName()
+ "/"
+ (config.getResource() != null ? config.getResource() : "Test");
} }
@Override @Override
@ -104,11 +117,7 @@ public class DummyConnection extends AbstractXMPPConnection {
@Override @Override
protected void loginNonAnonymously(String username, String password, String resource) protected void loginNonAnonymously(String username, String password, String resource)
throws XMPPException { throws XMPPException {
user = username user = getUserJid();
+ "@"
+ config.getServiceName()
+ "/"
+ (resource != null ? resource : "Test");
authenticated = true; authenticated = true;
} }

View file

@ -22,6 +22,9 @@ import static org.junit.Assert.assertFalse;
import org.jivesoftware.smack.filter.FromMatchesFilter; import org.jivesoftware.smack.filter.FromMatchesFilter;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.junit.Test; import org.junit.Test;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.JidTestUtil;
/** /**
* *
@ -29,16 +32,16 @@ import org.junit.Test;
* *
*/ */
public class FromMatchesFilterTest { public class FromMatchesFilterTest {
private static final String BASE_JID1 = "ss@muc.myserver.com"; private static final Jid BASE_JID1 = JidTestUtil.BARE_JID_1;
private static final String FULL_JID1_R1 = BASE_JID1 + "/resource"; private static final FullJid FULL_JID1_R1 = JidTestUtil.FULL_JID_1_RESOURCE_1;
private static final String FULL_JID1_R2 = BASE_JID1 + "/resource2"; private static final FullJid FULL_JID1_R2 = JidTestUtil.FULL_JID_1_RESOURCE_2;
private static final String BASE_JID2 = "sss@muc.myserver.com"; private static final Jid BASE_JID2 = JidTestUtil.BARE_JID_2;
private static final String FULL_JID2 = BASE_JID2 + "/resource"; private static final Jid FULL_JID2 = JidTestUtil.FULL_JID_2_RESOURCE_1;
private static final String BASE_JID3 = "ss@muc.myserver.comm.net"; private static final Jid BASE_JID3 = JidTestUtil.DUMMY_AT_EXAMPLE_ORG;
private static final String SERVICE_JID1 = "muc.myserver.com"; private static final Jid SERVICE_JID1 = JidTestUtil.MUC_EXAMPLE_ORG;
private static final String SERVICE_JID2 = "pubsub.myserver.com"; private static final Jid SERVICE_JID2 = JidTestUtil.PUBSUB_EXAMPLE_ORG;
@Test @Test
public void autoCompareMatchingFullJid() public void autoCompareMatchingFullJid()

View file

@ -22,6 +22,8 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import org.junit.Test; import org.junit.Test;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
/** /**
* Tests that verifies the correct behavior of creating result and error IQ packets. * Tests that verifies the correct behavior of creating result and error IQ packets.
@ -36,12 +38,13 @@ public class IQResponseTest {
/** /**
* Test creating a simple and empty IQ response. * Test creating a simple and empty IQ response.
* @throws XmppStringprepException
*/ */
@Test @Test
public void testGeneratingSimpleResponse() { public void testGeneratingSimpleResponse() throws XmppStringprepException {
final IQ request = new TestIQ(ELEMENT, NAMESPACE); final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setFrom("sender@test/Smack"); request.setFrom(JidCreate.from("sender@test/Smack"));
request.setTo("receiver@test/Smack"); request.setTo(JidCreate.from("receiver@test/Smack"));
final IQ result = IQ.createResultIQ(request); final IQ result = IQ.createResultIQ(request);
@ -55,15 +58,16 @@ public class IQResponseTest {
/** /**
* Test creating a error response based on an IQ request. * Test creating a error response based on an IQ request.
* @throws XmppStringprepException
*/ */
@Test @Test
public void testGeneratingValidErrorResponse() { public void testGeneratingValidErrorResponse() throws XmppStringprepException {
final XMPPError error = new XMPPError(XMPPError.Condition.bad_request); final XMPPError error = new XMPPError(XMPPError.Condition.bad_request);
final IQ request = new TestIQ(ELEMENT, NAMESPACE); final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setType(IQ.Type.set); request.setType(IQ.Type.set);
request.setFrom("sender@test/Smack"); request.setFrom(JidCreate.from("sender@test/Smack"));
request.setTo("receiver@test/Smack"); request.setTo(JidCreate.from("receiver@test/Smack"));
final IQ result = IQ.createErrorResponse(request, error); final IQ result = IQ.createErrorResponse(request, error);
@ -79,14 +83,15 @@ public class IQResponseTest {
/** /**
* According to <a href="http://xmpp.org/rfcs/rfc3920.html#stanzas-semantics-iq" * According to <a href="http://xmpp.org/rfcs/rfc3920.html#stanzas-semantics-iq"
* >RFC3920: IQ Semantics</a> we shouldn't respond to an IQ of type result. * >RFC3920: IQ Semantics</a> we shouldn't respond to an IQ of type result.
* @throws XmppStringprepException
*/ */
@Test @Test
public void testGeneratingResponseBasedOnResult() { public void testGeneratingResponseBasedOnResult() throws XmppStringprepException {
final IQ request = new TestIQ(ELEMENT, NAMESPACE); final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setType(IQ.Type.result); request.setType(IQ.Type.result);
request.setFrom("sender@test/Smack"); request.setFrom(JidCreate.from("sender@test/Smack"));
request.setTo("receiver@test/Smack"); request.setTo(JidCreate.from("receiver@test/Smack"));
try { try {
IQ.createResultIQ(request); IQ.createResultIQ(request);
@ -101,15 +106,16 @@ public class IQResponseTest {
/** /**
* According to <a href="http://xmpp.org/rfcs/rfc3920.html#stanzas-semantics-iq" * According to <a href="http://xmpp.org/rfcs/rfc3920.html#stanzas-semantics-iq"
* >RFC3920: IQ Semantics</a> we shouldn't respond to an IQ of type error. * >RFC3920: IQ Semantics</a> we shouldn't respond to an IQ of type error.
* @throws XmppStringprepException
*/ */
@Test @Test
public void testGeneratingErrorBasedOnError() { public void testGeneratingErrorBasedOnError() throws XmppStringprepException {
final XMPPError error = new XMPPError(XMPPError.Condition.bad_request); final XMPPError error = new XMPPError(XMPPError.Condition.bad_request);
final IQ request = new TestIQ(ELEMENT, NAMESPACE); final IQ request = new TestIQ(ELEMENT, NAMESPACE);
request.setType(IQ.Type.error); request.setType(IQ.Type.error);
request.setFrom("sender@test/Smack"); request.setFrom(JidCreate.from("sender@test/Smack"));
request.setTo("receiver@test/Smack"); request.setTo(JidCreate.from("receiver@test/Smack"));
request.setError(error); request.setError(error);
try { try {

View file

@ -25,6 +25,8 @@ import java.util.Map;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
public class DigestMd5SaslTest extends AbstractSaslTest { public class DigestMd5SaslTest extends AbstractSaslTest {
@ -35,8 +37,8 @@ public class DigestMd5SaslTest extends AbstractSaslTest {
super(saslMechanism); super(saslMechanism);
} }
protected void runTest() throws NotConnectedException, SmackException, InterruptedException { protected void runTest() throws NotConnectedException, SmackException, InterruptedException, XmppStringprepException {
saslMechanism.authenticate("florian", "irrelevant", "xmpp.org", "secret"); saslMechanism.authenticate("florian", "irrelevant", JidCreate.domainBareFrom("xmpp.org"), "secret");
byte[] response = saslMechanism.evaluateChallenge(challengeBytes); byte[] response = saslMechanism.evaluateChallenge(challengeBytes);
String responseString = new String(response); String responseString = new String(response);

View file

@ -27,6 +27,7 @@ import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smack.util.stringencoder.Base64;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.jxmpp.jid.JidTestUtil;
public class SCRAMSHA1MechanismTest { public class SCRAMSHA1MechanismTest {
@ -53,7 +54,7 @@ public class SCRAMSHA1MechanismTest {
} }
}; };
mech.authenticate(USERNAME, "unusedFoo", "unusedBar", PASSWORD); mech.authenticate(USERNAME, "unusedFoo", JidTestUtil.DOMAIN_BARE_JID_1, PASSWORD);
AuthMechanism authMechanism = con.getSentPacket(); AuthMechanism authMechanism = con.getSentPacket();
assertEquals(SCRAMSHA1Mechanism.NAME, authMechanism.getMechanism()); assertEquals(SCRAMSHA1Mechanism.NAME, authMechanism.getMechanism());
assertEquals(CLIENT_FIRST_MESSAGE, saslLayerString(authMechanism.getAuthenticationText())); assertEquals(CLIENT_FIRST_MESSAGE, saslLayerString(authMechanism.getAuthenticationText()));

View file

@ -43,7 +43,7 @@ public class WaitForPacketListener implements PacketListener {
public void waitUntilInvocationOrTimeout() { public void waitUntilInvocationOrTimeout() {
try { try {
boolean res = latch.await(30, TimeUnit.SECONDS); boolean res = latch.await(300, TimeUnit.SECONDS);
if (!res) { if (!res) {
throw new IllegalStateException("Latch timed out before it reached zero"); throw new IllegalStateException("Latch timed out before it reached zero");
} }

View file

@ -23,7 +23,7 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.util.ObservableReader; import org.jivesoftware.smack.util.ObservableReader;
import org.jivesoftware.smack.util.ObservableWriter; import org.jivesoftware.smack.util.ObservableWriter;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.FullJid;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -93,18 +93,9 @@ public class SLF4JSmackDebugger implements SmackDebugger {
} }
@Override @Override
public void userHasLogged(String user) { public void userHasLogged(FullJid user) {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
String userTitle = getUserTitle(user); logger.debug("({}) User logged in {}", connection.hashCode(), user.toString());
logger.debug("({}) User logged in {}", connection.hashCode(), userTitle);
}
}
private String getUserTitle(String user) {
if (("@" + connection.getServiceName()).equals(XmppStringUtils.parseBareJid(user))) {
return "<Anonymous>@" + connection.getServiceName();
} else {
return user;
} }
} }

View file

@ -32,6 +32,8 @@ import org.jivesoftware.smack.util.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener; import org.jivesoftware.smack.util.ReaderListener;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.WriterListener; import org.jivesoftware.smack.util.WriterListener;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
@ -735,12 +737,13 @@ public class EnhancedDebugger implements SmackDebugger {
return writer; return writer;
} }
public void userHasLogged(final String user) { @Override
public void userHasLogged(final FullJid user) {
final EnhancedDebugger debugger = this; final EnhancedDebugger debugger = this;
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
userField.setText(user); userField.setText(user.toString());
EnhancedDebuggerWindow.userHasLogged(debugger, user); EnhancedDebuggerWindow.userHasLogged(debugger, user.toString());
// Add the connection listener to the connection so that the debugger can be notified // Add the connection listener to the connection so that the debugger can be notified
// whenever the connection is closed. // whenever the connection is closed.
connection.addConnectionListener(connListener); connection.addConnectionListener(connListener);
@ -795,7 +798,7 @@ public class EnhancedDebugger implements SmackDebugger {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
String messageType; String messageType;
String from = packet.getFrom(); Jid from = packet.getFrom();
String type = ""; String type = "";
Icon packetTypeIcon; Icon packetTypeIcon;
receivedPackets++; receivedPackets++;
@ -856,7 +859,7 @@ public class EnhancedDebugger implements SmackDebugger {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
String messageType; String messageType;
String to = packet.getTo(); Jid to = packet.getTo();
String type = ""; String type = "";
Icon packetTypeIcon; Icon packetTypeIcon;
sentPackets++; sentPackets++;

View file

@ -48,7 +48,7 @@ import org.jivesoftware.smack.util.ObservableReader;
import org.jivesoftware.smack.util.ObservableWriter; import org.jivesoftware.smack.util.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener; import org.jivesoftware.smack.util.ReaderListener;
import org.jivesoftware.smack.util.WriterListener; import org.jivesoftware.smack.util.WriterListener;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.FullJid;
/** /**
* The LiteDebugger is a very simple debugger that allows to debug sent, received and * The LiteDebugger is a very simple debugger that allows to debug sent, received and
@ -324,16 +324,11 @@ public class LiteDebugger implements SmackDebugger {
return writer; return writer;
} }
public void userHasLogged(String user) { @Override
boolean isAnonymous = "".equals(XmppStringUtils.parseLocalpart(user)); public void userHasLogged(FullJid user) {
String title = String title =
"Smack Debug Window -- " "Smack Debug Window -- "
+ (isAnonymous ? "" : XmppStringUtils.parseBareJid(user)) + user;
+ "@"
+ connection.getServiceName()
+ ":"
+ connection.getPort();
title += "/" + XmppStringUtils.parseResource(user);
frame.setTitle(title); frame.setTitle(title);
} }

View file

@ -24,6 +24,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.hoxt.packet.AbstractHttpOverXmpp; import org.jivesoftware.smackx.hoxt.packet.AbstractHttpOverXmpp;
import org.jxmpp.jid.Jid;
/** /**
* Manager for HTTP ove XMPP transport (XEP-0332) extension. * Manager for HTTP ove XMPP transport (XEP-0332) extension.
@ -58,7 +59,7 @@ public class HOXTManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public static boolean isSupported(String jid, XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public static boolean isSupported(Jid jid, XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(jid, NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(jid, NAMESPACE);
} }
} }

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smackx.carbons; package org.jivesoftware.smackx.carbons;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.jivesoftware.smack.test.util.CharsequenceEquals.equalsCharSequence;
import java.util.Properties; import java.util.Properties;
@ -62,7 +64,7 @@ public class CarbonTest extends ExperimentalInitializerTest {
assertEquals(null, fwd.getDelayInformation()); assertEquals(null, fwd.getDelayInformation());
// check message // check message
assertEquals("romeo@montague.com", fwd.getForwardedPacket().getFrom()); assertThat("romeo@montague.com", equalsCharSequence(fwd.getForwardedPacket().getFrom()));
// check end of tag // check end of tag
assertEquals(XmlPullParser.END_TAG, parser.getEventType()); assertEquals(XmlPullParser.END_TAG, parser.getEventType());

View file

@ -18,6 +18,7 @@
package org.jivesoftware.smackx.address; package org.jivesoftware.smackx.address;
import org.jivesoftware.smackx.address.packet.MultipleAddresses; import org.jivesoftware.smackx.address.packet.MultipleAddresses;
import org.jxmpp.jid.Jid;
import java.util.List; import java.util.List;
@ -64,7 +65,8 @@ public class MultipleRecipientInfo {
* @return the JID of a MUC room to which responses should be sent or <tt>null</tt> if * @return the JID of a MUC room to which responses should be sent or <tt>null</tt> if
* no specific address was provided. * no specific address was provided.
*/ */
public String getReplyRoom() { // TODO should return BareJid
public Jid getReplyRoom() {
List<MultipleAddresses.Address> replyRoom = extension.getAddressesOfType(MultipleAddresses.Type.replyroom); List<MultipleAddresses.Address> replyRoom = extension.getAddressesOfType(MultipleAddresses.Type.replyroom);
return replyRoom.isEmpty() ? null : ((MultipleAddresses.Address) replyRoom.get(0)).getJid(); return replyRoom.isEmpty() ? null : ((MultipleAddresses.Address) replyRoom.get(0)).getJid();
} }

View file

@ -28,7 +28,10 @@ import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.address.packet.MultipleAddresses; import org.jivesoftware.smackx.address.packet.MultipleAddresses;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -66,7 +69,7 @@ public class MultipleRecipientManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public static void send(XMPPConnection connection, Stanza packet, Collection<String> to, Collection<String> cc, Collection<String> bcc) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException, InterruptedException public static void send(XMPPConnection connection, Stanza packet, Collection<? extends Jid> to, Collection<? extends Jid> cc, Collection<? extends Jid> bcc) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException, InterruptedException
{ {
send(connection, packet, to, cc, bcc, null, null, false); send(connection, packet, to, cc, bcc, null, null, false);
} }
@ -96,18 +99,18 @@ public class MultipleRecipientManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public static void send(XMPPConnection connection, Stanza packet, Collection<String> to, Collection<String> cc, Collection<String> bcc, public static void send(XMPPConnection connection, Stanza packet, Collection<? extends Jid> to, Collection<? extends Jid> cc, Collection<? extends Jid> bcc,
String replyTo, String replyRoom, boolean noReply) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException, InterruptedException { Jid replyTo, Jid replyRoom, boolean noReply) throws NoResponseException, XMPPErrorException, FeatureNotSupportedException, NotConnectedException, InterruptedException {
// Check if *only* 'to' is set and contains just *one* entry, in this case extended stanzas addressing is not // Check if *only* 'to' is set and contains just *one* entry, in this case extended stanzas addressing is not
// required at all and we can send it just as normal stanza without needing to add the extension element // required at all and we can send it just as normal stanza without needing to add the extension element
if (to != null && to.size() == 1 && (cc == null || cc.isEmpty()) && (bcc == null || bcc.isEmpty()) && !noReply if (to != null && to.size() == 1 && (cc == null || cc.isEmpty()) && (bcc == null || bcc.isEmpty()) && !noReply
&& StringUtils.isNullOrEmpty(replyTo) && StringUtils.isNullOrEmpty(replyRoom)) { && StringUtils.isNullOrEmpty(replyTo) && StringUtils.isNullOrEmpty(replyRoom)) {
String toJid = to.iterator().next(); Jid toJid = to.iterator().next();
packet.setTo(toJid); packet.setTo(toJid);
connection.sendPacket(packet); connection.sendPacket(packet);
return; return;
} }
String serviceAddress = getMultipleRecipienServiceAddress(connection); DomainBareJid serviceAddress = getMultipleRecipienServiceAddress(connection);
if (serviceAddress != null) { if (serviceAddress != null) {
// Send packet to target users using multiple recipient service provided by the server // Send packet to target users using multiple recipient service provided by the server
sendThroughService(connection, packet, to, cc, bcc, replyTo, replyRoom, noReply, sendThroughService(connection, packet, to, cc, bcc, replyTo, replyRoom, noReply,
@ -115,8 +118,8 @@ public class MultipleRecipientManager {
} }
else { else {
// Server does not support XEP-33 so try to send the packet to each recipient // Server does not support XEP-33 so try to send the packet to each recipient
if (noReply || (replyTo != null && replyTo.trim().length() > 0) || if (noReply || replyTo != null ||
(replyRoom != null && replyRoom.trim().length() > 0)) { replyRoom != null) {
// Some specified XEP-33 features were requested so throw an exception alerting // Some specified XEP-33 features were requested so throw an exception alerting
// the user that this features are not available // the user that this features are not available
throw new FeatureNotSupportedException("Extended Stanza Addressing"); throw new FeatureNotSupportedException("Extended Stanza Addressing");
@ -162,8 +165,8 @@ public class MultipleRecipientManager {
} }
else { else {
// Send reply to multiple recipients // Send reply to multiple recipients
List<String> to = new ArrayList<String>(info.getTOAddresses().size()); List<Jid> to = new ArrayList<>(info.getTOAddresses().size());
List<String> cc = new ArrayList<String>(info.getCCAddresses().size()); List<Jid> cc = new ArrayList<>(info.getCCAddresses().size());
for (MultipleAddresses.Address jid : info.getTOAddresses()) { for (MultipleAddresses.Address jid : info.getTOAddresses()) {
to.add(jid.getJid()); to.add(jid.getJid());
} }
@ -175,9 +178,9 @@ public class MultipleRecipientManager {
to.add(original.getFrom()); to.add(original.getFrom());
} }
// Remove the sender from the TO/CC list (try with bare JID too) // Remove the sender from the TO/CC list (try with bare JID too)
String from = connection.getUser(); FullJid from = connection.getUser();
if (!to.remove(from) && !cc.remove(from)) { if (!to.remove(from) && !cc.remove(from)) {
String bareJID = XmppStringUtils.parseBareJid(from); BareJid bareJID = from.asBareJid();
to.remove(bareJID); to.remove(bareJID);
cc.remove(bareJID); cc.remove(bareJID);
} }
@ -202,44 +205,44 @@ public class MultipleRecipientManager {
} }
private static void sendToIndividualRecipients(XMPPConnection connection, Stanza packet, private static void sendToIndividualRecipients(XMPPConnection connection, Stanza packet,
Collection<String> to, Collection<String> cc, Collection<String> bcc) throws NotConnectedException, InterruptedException { Collection<? extends Jid> to, Collection<? extends Jid> cc, Collection<? extends Jid> bcc) throws NotConnectedException, InterruptedException {
if (to != null) { if (to != null) {
for (String jid : to) { for (Jid jid : to) {
packet.setTo(jid); packet.setTo(jid);
connection.sendPacket(new PacketCopy(packet.toXML())); connection.sendPacket(new PacketCopy(packet.toXML()));
} }
} }
if (cc != null) { if (cc != null) {
for (String jid : cc) { for (Jid jid : cc) {
packet.setTo(jid); packet.setTo(jid);
connection.sendPacket(new PacketCopy(packet.toXML())); connection.sendPacket(new PacketCopy(packet.toXML()));
} }
} }
if (bcc != null) { if (bcc != null) {
for (String jid : bcc) { for (Jid jid : bcc) {
packet.setTo(jid); packet.setTo(jid);
connection.sendPacket(new PacketCopy(packet.toXML())); connection.sendPacket(new PacketCopy(packet.toXML()));
} }
} }
} }
private static void sendThroughService(XMPPConnection connection, Stanza packet, Collection<String> to, private static void sendThroughService(XMPPConnection connection, Stanza packet, Collection<? extends Jid> to,
Collection<String> cc, Collection<String> bcc, String replyTo, String replyRoom, boolean noReply, Collection<? extends Jid> cc, Collection<? extends Jid> bcc, Jid replyTo, Jid replyRoom, boolean noReply,
String serviceAddress) throws NotConnectedException, InterruptedException { DomainBareJid serviceAddress) throws NotConnectedException, InterruptedException {
// Create multiple recipient extension // Create multiple recipient extension
MultipleAddresses multipleAddresses = new MultipleAddresses(); MultipleAddresses multipleAddresses = new MultipleAddresses();
if (to != null) { if (to != null) {
for (String jid : to) { for (Jid jid : to) {
multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null); multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null);
} }
} }
if (cc != null) { if (cc != null) {
for (String jid : cc) { for (Jid jid : cc) {
multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null); multipleAddresses.addAddress(MultipleAddresses.Type.to, jid, null, null, false, null);
} }
} }
if (bcc != null) { if (bcc != null) {
for (String jid : bcc) { for (Jid jid : bcc) {
multipleAddresses.addAddress(MultipleAddresses.Type.bcc, jid, null, null, false, null); multipleAddresses.addAddress(MultipleAddresses.Type.bcc, jid, null, null, false, null);
} }
} }
@ -247,11 +250,11 @@ public class MultipleRecipientManager {
multipleAddresses.setNoReply(); multipleAddresses.setNoReply();
} }
else { else {
if (replyTo != null && replyTo.trim().length() > 0) { if (replyTo != null) {
multipleAddresses multipleAddresses
.addAddress(MultipleAddresses.Type.replyto, replyTo, null, null, false, null); .addAddress(MultipleAddresses.Type.replyto, replyTo, null, null, false, null);
} }
if (replyRoom != null && replyRoom.trim().length() > 0) { if (replyRoom != null) {
multipleAddresses.addAddress(MultipleAddresses.Type.replyroom, replyRoom, null, null, multipleAddresses.addAddress(MultipleAddresses.Type.replyroom, replyRoom, null, null,
false, null); false, null);
} }
@ -278,9 +281,9 @@ public class MultipleRecipientManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
private static String getMultipleRecipienServiceAddress(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private static DomainBareJid getMultipleRecipienServiceAddress(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
List<String> services = sdm.findServices(MultipleAddresses.NAMESPACE, true, true); List<DomainBareJid> services = sdm.findServices(MultipleAddresses.NAMESPACE, true, true);
if (services.size() > 0) { if (services.size() > 0) {
return services.get(0); return services.get(0);
} }

View file

@ -20,6 +20,7 @@ package org.jivesoftware.smackx.address.packet;
import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -64,7 +65,7 @@ public class MultipleAddresses implements PacketExtension {
* @param delivered true when the packet was already delivered to this address. * @param delivered true when the packet was already delivered to this address.
* @param uri used to specify an external system address, such as a sip:, sips:, or im: URI. * @param uri used to specify an external system address, such as a sip:, sips:, or im: URI.
*/ */
public void addAddress(Type type, String jid, String node, String desc, boolean delivered, public void addAddress(Type type, Jid jid, String node, String desc, boolean delivered,
String uri) { String uri) {
// Create a new address with the specificed configuration // Create a new address with the specificed configuration
Address address = new Address(type); Address address = new Address(type);
@ -132,7 +133,7 @@ public class MultipleAddresses implements PacketExtension {
public static final String ELEMENT = "address"; public static final String ELEMENT = "address";
private final Type type; private final Type type;
private String jid; private Jid jid;
private String node; private String node;
private String description; private String description;
private boolean delivered; private boolean delivered;
@ -146,11 +147,11 @@ public class MultipleAddresses implements PacketExtension {
return type; return type;
} }
public String getJid() { public Jid getJid() {
return jid; return jid;
} }
private void setJid(String jid) { private void setJid(Jid jid) {
this.jid = jid; this.jid = jid;
} }

View file

@ -20,8 +20,10 @@ package org.jivesoftware.smackx.address.provider;
import java.io.IOException; import java.io.IOException;
import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.jivesoftware.smack.provider.PacketExtensionProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.address.packet.MultipleAddresses; import org.jivesoftware.smackx.address.packet.MultipleAddresses;
import org.jivesoftware.smackx.address.packet.MultipleAddresses.Type; import org.jivesoftware.smackx.address.packet.MultipleAddresses.Type;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -46,7 +48,7 @@ public class MultipleAddressesProvider extends PacketExtensionProvider<MultipleA
case MultipleAddresses.Address.ELEMENT: case MultipleAddresses.Address.ELEMENT:
String typeString = parser.getAttributeValue("", "type"); String typeString = parser.getAttributeValue("", "type");
Type type = Type.valueOf(typeString); Type type = Type.valueOf(typeString);
String jid = parser.getAttributeValue("", "jid"); Jid jid = ParserUtils.getJidAttribute(parser, "jid");
String node = parser.getAttributeValue("", "node"); String node = parser.getAttributeValue("", "node");
String desc = parser.getAttributeValue("", "desc"); String desc = parser.getAttributeValue("", "desc");
boolean delivered = "true".equals(parser.getAttributeValue("", "delivered")); boolean delivered = "true".equals(parser.getAttributeValue("", "delivered"));

View file

@ -90,7 +90,7 @@ public class AMPManager {
*/ */
public static boolean isActionSupported(XMPPConnection connection, AMPExtension.Action action) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public static boolean isActionSupported(XMPPConnection connection, AMPExtension.Action action) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
String featureName = AMPExtension.NAMESPACE + "?action=" + action.toString(); String featureName = AMPExtension.NAMESPACE + "?action=" + action.toString();
return isFeatureSupportedByServer(connection, featureName, AMPExtension.NAMESPACE); return isFeatureSupportedByServer(connection, featureName);
} }
/** /**
@ -108,10 +108,10 @@ public class AMPManager {
*/ */
public static boolean isConditionSupported(XMPPConnection connection, String conditionName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public static boolean isConditionSupported(XMPPConnection connection, String conditionName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
String featureName = AMPExtension.NAMESPACE + "?condition=" + conditionName; String featureName = AMPExtension.NAMESPACE + "?condition=" + conditionName;
return isFeatureSupportedByServer(connection, featureName, AMPExtension.NAMESPACE); return isFeatureSupportedByServer(connection, featureName);
} }
private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(node, featureName); return ServiceDiscoveryManager.getInstanceFor(connection).serverSupportsFeature(featureName);
} }
} }

View file

@ -30,7 +30,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
* <p> * <p>
* There are two ways to add this listener. See * There are two ways to add this listener. See
* {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
* {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for further * {@link BytestreamManager#addIncomingBytestreamListener(BytestreamListener, org.jxmpp.jid.Jid)} for further
* details. * details.
* <p> * <p>
* {@link Socks5BytestreamListener} or {@link InBandBytestreamListener} provide a more specific * {@link Socks5BytestreamListener} or {@link InBandBytestreamListener} provide a more specific

View file

@ -22,6 +22,7 @@ import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager;
import org.jxmpp.jid.Jid;
/** /**
* BytestreamManager provides a generic interface for bytestream managers. * BytestreamManager provides a generic interface for bytestream managers.
@ -58,14 +59,14 @@ public interface BytestreamManager {
* <p> * <p>
* Use this method if you are awaiting an incoming bytestream request from a specific user. * Use this method if you are awaiting an incoming bytestream request from a specific user.
* <p> * <p>
* See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} * See {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, Jid)}
* and {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} * and {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, Jid)}
* for further details. * for further details.
* *
* @param listener the listener to register * @param listener the listener to register
* @param initiatorJID the JID of the user that wants to establish a bytestream * @param initiatorJID the JID of the user that wants to establish a bytestream
*/ */
public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID); public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID);
/** /**
* Removes the listener for the given user. * Removes the listener for the given user.
@ -82,10 +83,10 @@ public interface BytestreamManager {
* since this method doesn't provide a way to tell the user something about the data to be sent. * since this method doesn't provide a way to tell the user something about the data to be sent.
* <p> * <p>
* To establish a bytestream after negotiation the kind of data to be sent (e.g. file transfer) * To establish a bytestream after negotiation the kind of data to be sent (e.g. file transfer)
* use {@link #establishSession(String, String)}. * use {@link #establishSession(Jid, String)}.
* <p> * <p>
* See {@link Socks5BytestreamManager#establishSession(String)} and * See {@link Socks5BytestreamManager#establishSession(Jid)} and
* {@link InBandBytestreamManager#establishSession(String)} for further details. * {@link InBandBytestreamManager#establishSession(Jid)} for further details.
* *
* @param targetJID the JID of the user a bytestream should be established * @param targetJID the JID of the user a bytestream should be established
* @return the session to send/receive data to/from the user * @return the session to send/receive data to/from the user
@ -94,15 +95,15 @@ public interface BytestreamManager {
* @throws InterruptedException if the thread was interrupted while waiting in a blocking * @throws InterruptedException if the thread was interrupted while waiting in a blocking
* operation * operation
*/ */
public BytestreamSession establishSession(String targetJID) throws XMPPException, IOException, public BytestreamSession establishSession(Jid targetJID) throws XMPPException, IOException,
InterruptedException, SmackException; InterruptedException, SmackException;
/** /**
* Establishes a bytestream with the given user and returns the session to send/receive data * Establishes a bytestream with the given user and returns the session to send/receive data
* to/from the user. * to/from the user.
* <p> * <p>
* See {@link Socks5BytestreamManager#establishSession(String)} and * See {@link Socks5BytestreamManager#establishSession(Jid)} and
* {@link InBandBytestreamManager#establishSession(String)} for further details. * {@link InBandBytestreamManager#establishSession(Jid)} for further details.
* *
* @param targetJID the JID of the user a bytestream should be established * @param targetJID the JID of the user a bytestream should be established
* @param sessionID the session ID for the bytestream request * @param sessionID the session ID for the bytestream request
@ -112,7 +113,7 @@ public interface BytestreamManager {
* @throws InterruptedException if the thread was interrupted while waiting in a blocking * @throws InterruptedException if the thread was interrupted while waiting in a blocking
* operation * operation
*/ */
public BytestreamSession establishSession(String targetJID, String sessionID) public BytestreamSession establishSession(Jid targetJID, String sessionID)
throws XMPPException, IOException, InterruptedException, SmackException; throws XMPPException, IOException, InterruptedException, SmackException;
} }

View file

@ -22,6 +22,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamRequest;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
import org.jxmpp.jid.Jid;
/** /**
* BytestreamRequest provides an interface to handle incoming bytestream requests. * BytestreamRequest provides an interface to handle incoming bytestream requests.
@ -38,7 +39,7 @@ public interface BytestreamRequest {
* *
* @return the sender of the bytestream open request * @return the sender of the bytestream open request
*/ */
public String getFrom(); public Jid getFrom();
/** /**
* Returns the session ID of the bytestream open request. * Returns the session ID of the bytestream open request.

View file

@ -25,7 +25,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
* <p> * <p>
* There are two ways to add this listener. See * There are two ways to add this listener. See
* {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
* {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for * {@link InBandBytestreamManager#addIncomingBytestreamListener(BytestreamListener, org.jxmpp.jid.Jid)} for
* further details. * further details.
* *
* @author Henning Staib * @author Henning Staib

View file

@ -39,6 +39,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamListener;
import org.jivesoftware.smackx.bytestreams.BytestreamManager; import org.jivesoftware.smackx.bytestreams.BytestreamManager;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
import org.jivesoftware.smackx.filetransfer.FileTransferManager; import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jxmpp.jid.Jid;
/** /**
* The InBandBytestreamManager class handles establishing In-Band Bytestreams as specified in the <a * The InBandBytestreamManager class handles establishing In-Band Bytestreams as specified in the <a
@ -55,16 +56,16 @@ import org.jivesoftware.smackx.filetransfer.FileTransferManager;
* flow-control method like <a href="http://xmpp.org/extensions/xep-0079.html">Advanced Message * flow-control method like <a href="http://xmpp.org/extensions/xep-0079.html">Advanced Message
* Processing</a>. To set the stanza that should be used invoke {@link #setStanza(StanzaType)}. * Processing</a>. To set the stanza that should be used invoke {@link #setStanza(StanzaType)}.
* <p> * <p>
* To establish an In-Band Bytestream invoke the {@link #establishSession(String)} method. This will * To establish an In-Band Bytestream invoke the {@link #establishSession(Jid)} method. This will
* negotiate an in-band bytestream with the given target JID and return a session. * negotiate an in-band bytestream with the given target JID and return a session.
* <p> * <p>
* If a session ID for the In-Band Bytestream was already negotiated (e.g. while negotiating a file * If a session ID for the In-Band Bytestream was already negotiated (e.g. while negotiating a file
* transfer) invoke {@link #establishSession(String, String)}. * transfer) invoke {@link #establishSession(Jid, String)}.
* <p> * <p>
* To handle incoming In-Band Bytestream requests add an {@link InBandBytestreamListener} to the * To handle incoming In-Band Bytestream requests add an {@link InBandBytestreamListener} to the
* manager. There are two ways to add this listener. If you want to be informed about incoming * manager. There are two ways to add this listener. If you want to be informed about incoming
* In-Band Bytestreams from a specific user add the listener by invoking * In-Band Bytestreams from a specific user add the listener by invoking
* {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should * {@link #addIncomingBytestreamListener(BytestreamListener, Jid)}. If the listener should
* respond to all In-Band Bytestream requests invoke * respond to all In-Band Bytestream requests invoke
* {@link #addIncomingBytestreamListener(BytestreamListener)}. * {@link #addIncomingBytestreamListener(BytestreamListener)}.
* <p> * <p>
@ -147,7 +148,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* assigns a user to a listener that is informed if an In-Band Bytestream request for this user * assigns a user to a listener that is informed if an In-Band Bytestream request for this user
* is received * is received
*/ */
private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>(); private final Map<Jid, BytestreamListener> userListeners = new ConcurrentHashMap<>();
/* /*
* list of listeners that respond to all In-Band Bytestream requests if there are no user * list of listeners that respond to all In-Band Bytestream requests if there are no user
@ -267,7 +268,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* @param listener the listener to register * @param listener the listener to register
* @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream * @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
*/ */
public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) { public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
this.userListeners.put(initiatorJID, listener); this.userListeners.put(initiatorJID, listener);
} }
@ -392,7 +393,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* the data to be sent. * the data to be sent.
* <p> * <p>
* To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file * To establish an In-Band Bytestream after negotiation the kind of data to be sent (e.g. file
* transfer) use {@link #establishSession(String, String)}. * transfer) use {@link #establishSession(Jid, String)}.
* *
* @param targetJID the JID of the user an In-Band Bytestream should be established * @param targetJID the JID of the user an In-Band Bytestream should be established
* @return the session to send/receive data to/from the user * @return the session to send/receive data to/from the user
@ -401,7 +402,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* @throws SmackException if there was no response from the server. * @throws SmackException if there was no response from the server.
* @throws InterruptedException * @throws InterruptedException
*/ */
public InBandBytestreamSession establishSession(String targetJID) throws XMPPException, SmackException, InterruptedException { public InBandBytestreamSession establishSession(Jid targetJID) throws XMPPException, SmackException, InterruptedException {
String sessionID = getNextSessionID(); String sessionID = getNextSessionID();
return establishSession(targetJID, sessionID); return establishSession(targetJID, sessionID);
} }
@ -419,7 +420,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public InBandBytestreamSession establishSession(String targetJID, String sessionID) public InBandBytestreamSession establishSession(Jid targetJID, String sessionID)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza); Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
byteStreamRequest.setTo(targetJID); byteStreamRequest.setTo(targetJID);
@ -504,7 +505,7 @@ public class InBandBytestreamManager implements BytestreamManager {
* @param initiator the initiator's JID * @param initiator the initiator's JID
* @return the listener * @return the listener
*/ */
protected BytestreamListener getUserListener(String initiator) { protected BytestreamListener getUserListener(Jid initiator) {
return this.userListeners.get(initiator); return this.userListeners.get(initiator);
} }

View file

@ -21,6 +21,7 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.bytestreams.BytestreamRequest; import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
import org.jxmpp.jid.Jid;
/** /**
* InBandBytestreamRequest class handles incoming In-Band Bytestream requests. * InBandBytestreamRequest class handles incoming In-Band Bytestream requests.
@ -49,7 +50,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
* *
* @return the sender of the In-Band Bytestream open request * @return the sender of the In-Band Bytestream open request
*/ */
public String getFrom() { public Jid getFrom() {
return this.byteStreamRequest.getFrom(); return this.byteStreamRequest.getFrom();
} }

View file

@ -40,6 +40,7 @@ import org.jivesoftware.smackx.bytestreams.ibb.packet.Close;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Data; import org.jivesoftware.smackx.bytestreams.ibb.packet.Data;
import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension; import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
import org.jxmpp.jid.Jid;
/** /**
* InBandBytestreamSession class represents an In-Band Bytestream session. * InBandBytestreamSession class represents an In-Band Bytestream session.
@ -73,7 +74,7 @@ public class InBandBytestreamSession implements BytestreamSession {
private IBBOutputStream outputStream; private IBBOutputStream outputStream;
/* JID of the remote peer */ /* JID of the remote peer */
private String remoteJID; private Jid remoteJID;
/* flag to close both streams if one of them is closed */ /* flag to close both streams if one of them is closed */
private boolean closeBothStreamsEnabled = false; private boolean closeBothStreamsEnabled = false;
@ -89,7 +90,7 @@ public class InBandBytestreamSession implements BytestreamSession {
* @param remoteJID JID of the remote peer * @param remoteJID JID of the remote peer
*/ */
protected InBandBytestreamSession(XMPPConnection connection, Open byteStreamRequest, protected InBandBytestreamSession(XMPPConnection connection, Open byteStreamRequest,
String remoteJID) { Jid remoteJID) {
this.connection = connection; this.connection = connection;
this.byteStreamRequest = byteStreamRequest; this.byteStreamRequest = byteStreamRequest;
this.remoteJID = remoteJID; this.remoteJID = remoteJID;
@ -556,7 +557,7 @@ public class InBandBytestreamSession implements BytestreamSession {
public boolean accept(Stanza packet) { public boolean accept(Stanza packet) {
// sender equals remote peer // sender equals remote peer
if (!packet.getFrom().equalsIgnoreCase(remoteJID)) { if (!packet.getFrom().equals(remoteJID)) {
return false; return false;
} }

View file

@ -25,7 +25,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
* <p> * <p>
* There are two ways to add this listener. See * There are two ways to add this listener. See
* {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener)} and
* {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, String)} for * {@link Socks5BytestreamManager#addIncomingBytestreamListener(BytestreamListener, org.jxmpp.jid.Jid)} for
* further details. * further details.
* *
* @author Henning Staib * @author Henning Staib

View file

@ -21,10 +21,12 @@ import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -51,6 +53,7 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.disco.packet.DiscoverItems.Item; import org.jivesoftware.smackx.disco.packet.DiscoverItems.Item;
import org.jivesoftware.smackx.filetransfer.FileTransferManager; import org.jivesoftware.smackx.filetransfer.FileTransferManager;
import org.jxmpp.jid.Jid;
/** /**
* The Socks5BytestreamManager class handles establishing SOCKS5 Bytestreams as specified in the <a * The Socks5BytestreamManager class handles establishing SOCKS5 Bytestreams as specified in the <a
@ -63,16 +66,16 @@ import org.jivesoftware.smackx.filetransfer.FileTransferManager;
* The stream host is a specialized SOCKS5 proxy setup on a server, or, the initiator can act as the * The stream host is a specialized SOCKS5 proxy setup on a server, or, the initiator can act as the
* stream host. * stream host.
* <p> * <p>
* To establish a SOCKS5 Bytestream invoke the {@link #establishSession(String)} method. This will * To establish a SOCKS5 Bytestream invoke the {@link #establishSession(Jid)} method. This will
* negotiate a SOCKS5 Bytestream with the given target JID and return a socket. * negotiate a SOCKS5 Bytestream with the given target JID and return a socket.
* <p> * <p>
* If a session ID for the SOCKS5 Bytestream was already negotiated (e.g. while negotiating a file * If a session ID for the SOCKS5 Bytestream was already negotiated (e.g. while negotiating a file
* transfer) invoke {@link #establishSession(String, String)}. * transfer) invoke {@link #establishSession(Jid, String)}.
* <p> * <p>
* To handle incoming SOCKS5 Bytestream requests add an {@link Socks5BytestreamListener} to the * To handle incoming SOCKS5 Bytestream requests add an {@link Socks5BytestreamListener} to the
* manager. There are two ways to add this listener. If you want to be informed about incoming * manager. There are two ways to add this listener. If you want to be informed about incoming
* SOCKS5 Bytestreams from a specific user add the listener by invoking * SOCKS5 Bytestreams from a specific user add the listener by invoking
* {@link #addIncomingBytestreamListener(BytestreamListener, String)}. If the listener should * {@link #addIncomingBytestreamListener(BytestreamListener, Jid)}. If the listener should
* respond to all SOCKS5 Bytestream requests invoke * respond to all SOCKS5 Bytestream requests invoke
* {@link #addIncomingBytestreamListener(BytestreamListener)}. * {@link #addIncomingBytestreamListener(BytestreamListener)}.
* <p> * <p>
@ -135,7 +138,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* assigns a user to a listener that is informed if a bytestream request for this user is * assigns a user to a listener that is informed if a bytestream request for this user is
* received * received
*/ */
private final Map<String, BytestreamListener> userListeners = new ConcurrentHashMap<String, BytestreamListener>(); private final Map<Jid, BytestreamListener> userListeners = new ConcurrentHashMap<>();
/* /*
* list of listeners that respond to all bytestream requests if there are not user specific * list of listeners that respond to all bytestream requests if there are not user specific
@ -153,10 +156,10 @@ public final class Socks5BytestreamManager implements BytestreamManager {
private int proxyConnectionTimeout = 10000; private int proxyConnectionTimeout = 10000;
/* blacklist of errornous SOCKS5 proxies */ /* blacklist of errornous SOCKS5 proxies */
private final List<String> proxyBlacklist = Collections.synchronizedList(new LinkedList<String>()); private final Set<Jid> proxyBlacklist = Collections.synchronizedSet(new HashSet<Jid>());
/* remember the last proxy that worked to prioritize it */ /* remember the last proxy that worked to prioritize it */
private String lastWorkingProxy = null; private Jid lastWorkingProxy;
/* flag to enable/disable prioritization of last working proxy */ /* flag to enable/disable prioritization of last working proxy */
private boolean proxyPrioritizationEnabled = true; private boolean proxyPrioritizationEnabled = true;
@ -246,7 +249,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @param listener the listener to register * @param listener the listener to register
* @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream * @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
*/ */
public void addIncomingBytestreamListener(BytestreamListener listener, String initiatorJID) { public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
this.userListeners.put(initiatorJID, listener); this.userListeners.put(initiatorJID, listener);
} }
@ -392,7 +395,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* the data to be sent. * the data to be sent.
* <p> * <p>
* To establish a SOCKS5 Bytestream after negotiation the kind of data to be sent (e.g. file * To establish a SOCKS5 Bytestream after negotiation the kind of data to be sent (e.g. file
* transfer) use {@link #establishSession(String, String)}. * transfer) use {@link #establishSession(Jid, String)}.
* *
* @param targetJID the JID of the user a SOCKS5 Bytestream should be established * @param targetJID the JID of the user a SOCKS5 Bytestream should be established
* @return the Socket to send/receive data to/from the user * @return the Socket to send/receive data to/from the user
@ -402,7 +405,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @throws InterruptedException if the current thread was interrupted while waiting * @throws InterruptedException if the current thread was interrupted while waiting
* @throws SmackException if there was no response from the server. * @throws SmackException if there was no response from the server.
*/ */
public Socks5BytestreamSession establishSession(String targetJID) throws XMPPException, public Socks5BytestreamSession establishSession(Jid targetJID) throws XMPPException,
IOException, InterruptedException, SmackException { IOException, InterruptedException, SmackException {
String sessionID = getNextSessionID(); String sessionID = getNextSessionID();
return establishSession(targetJID, sessionID); return establishSession(targetJID, sessionID);
@ -421,7 +424,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @throws SmackException if the target does not support SOCKS5. * @throws SmackException if the target does not support SOCKS5.
* @throws XMPPException * @throws XMPPException
*/ */
public Socks5BytestreamSession establishSession(String targetJID, String sessionID) public Socks5BytestreamSession establishSession(Jid targetJID, String sessionID)
throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{ throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{
XMPPErrorException discoveryException = null; XMPPErrorException discoveryException = null;
@ -430,7 +433,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
throw new FeatureNotSupportedException("SOCKS5 Bytestream", targetJID); throw new FeatureNotSupportedException("SOCKS5 Bytestream", targetJID);
} }
List<String> proxies = new ArrayList<String>(); List<Jid> proxies = new ArrayList<>();
// determine SOCKS5 proxies from XMPP-server // determine SOCKS5 proxies from XMPP-server
try { try {
proxies.addAll(determineProxies()); proxies.addAll(determineProxies());
@ -529,7 +532,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
private boolean supportsSocks5(String targetJID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private boolean supportsSocks5(Jid targetJID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(targetJID, Bytestream.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(targetJID, Bytestream.NAMESPACE);
} }
@ -543,10 +546,10 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
private List<String> determineProxies() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private List<Jid> determineProxies() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection); ServiceDiscoveryManager serviceDiscoveryManager = ServiceDiscoveryManager.getInstanceFor(this.connection);
List<String> proxies = new ArrayList<String>(); List<Jid> proxies = new ArrayList<>();
// get all items from XMPP server // get all items from XMPP server
DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(this.connection.getServiceName()); DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(this.connection.getServiceName());
@ -591,7 +594,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @param proxies a list of SOCKS5 proxy JIDs * @param proxies a list of SOCKS5 proxy JIDs
* @return a list of stream hosts containing the IP address an the port * @return a list of stream hosts containing the IP address an the port
*/ */
private List<StreamHost> determineStreamHostInfos(List<String> proxies) { private List<StreamHost> determineStreamHostInfos(List<Jid> proxies) {
List<StreamHost> streamHosts = new ArrayList<StreamHost>(); List<StreamHost> streamHosts = new ArrayList<StreamHost>();
// add local proxy on first position if exists // add local proxy on first position if exists
@ -601,7 +604,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
} }
// query SOCKS5 proxies for network settings // query SOCKS5 proxies for network settings
for (String proxy : proxies) { for (Jid proxy : proxies) {
Bytestream streamHostRequest = createStreamHostRequest(proxy); Bytestream streamHostRequest = createStreamHostRequest(proxy);
try { try {
Bytestream response = (Bytestream) connection.createPacketCollectorAndSend( Bytestream response = (Bytestream) connection.createPacketCollectorAndSend(
@ -623,7 +626,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @param proxy the proxy to query * @param proxy the proxy to query
* @return IQ packet to query a SOCKS5 proxy its network settings * @return IQ packet to query a SOCKS5 proxy its network settings
*/ */
private Bytestream createStreamHostRequest(String proxy) { private Bytestream createStreamHostRequest(Jid proxy) {
Bytestream request = new Bytestream(); Bytestream request = new Bytestream();
request.setType(IQ.Type.get); request.setType(IQ.Type.get);
request.setTo(proxy); request.setTo(proxy);
@ -678,7 +681,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @param streamHosts a list of SOCKS5 proxies the target should connect to * @param streamHosts a list of SOCKS5 proxies the target should connect to
* @return a SOCKS5 Bytestream initialization request packet * @return a SOCKS5 Bytestream initialization request packet
*/ */
private Bytestream createBytestreamInitiation(String sessionID, String targetJID, private Bytestream createBytestreamInitiation(String sessionID, Jid targetJID,
List<StreamHost> streamHosts) { List<StreamHost> streamHosts) {
Bytestream initiation = new Bytestream(sessionID); Bytestream initiation = new Bytestream(sessionID);
@ -758,7 +761,7 @@ public final class Socks5BytestreamManager implements BytestreamManager {
* @param initiator the initiator's JID * @param initiator the initiator's JID
* @return the listener * @return the listener
*/ */
protected BytestreamListener getUserListener(String initiator) { protected BytestreamListener getUserListener(Jid initiator) {
return this.userListeners.get(initiator); return this.userListeners.get(initiator);
} }

View file

@ -30,6 +30,7 @@ import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.bytestreams.BytestreamRequest; import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.cache.Cache; import org.jxmpp.util.cache.Cache;
import org.jxmpp.util.cache.ExpirationCache; import org.jxmpp.util.cache.ExpirationCache;
@ -169,7 +170,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
* *
* @return the sender of the SOCKS5 Bytestream initialization request. * @return the sender of the SOCKS5 Bytestream initialization request.
*/ */
public String getFrom() { public Jid getFrom() {
return this.bytestreamRequest.getFrom(); return this.bytestreamRequest.getFrom();
} }

View file

@ -29,6 +29,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
import org.jxmpp.jid.Jid;
/** /**
* Implementation of a SOCKS5 client used on the initiators side. This is needed because connecting * Implementation of a SOCKS5 client used on the initiators side. This is needed because connecting
@ -47,7 +48,8 @@ class Socks5ClientForInitiator extends Socks5Client {
private String sessionID; private String sessionID;
/* the target JID used to activate SOCKS5 stream */ /* the target JID used to activate SOCKS5 stream */
private String target; // TODO fullJid?
private final Jid target;
/** /**
* Creates a new SOCKS5 client for the initiators side. * Creates a new SOCKS5 client for the initiators side.
@ -59,7 +61,7 @@ class Socks5ClientForInitiator extends Socks5Client {
* @param target the target JID of the SOCKS5 Bytestream * @param target the target JID of the SOCKS5 Bytestream
*/ */
public Socks5ClientForInitiator(StreamHost streamHost, String digest, XMPPConnection connection, public Socks5ClientForInitiator(StreamHost streamHost, String digest, XMPPConnection connection,
String sessionID, String target) { String sessionID, Jid target) {
super(streamHost, digest); super(streamHost, digest);
this.connection = connection; this.connection = connection;
this.sessionID = sessionID; this.sessionID = sessionID;

View file

@ -54,7 +54,7 @@ import org.jivesoftware.smack.SmackException;
* <p> * <p>
* The local SOCKS5 proxy server refuses all connections except the ones that are explicitly allowed * The local SOCKS5 proxy server refuses all connections except the ones that are explicitly allowed
* in the process of establishing a SOCKS5 Bytestream ( * in the process of establishing a SOCKS5 Bytestream (
* {@link Socks5BytestreamManager#establishSession(String)}). * {@link Socks5BytestreamManager#establishSession(org.jxmpp.jid.Jid)}).
* <p> * <p>
* This Implementation has the following limitations: * This Implementation has the following limitations:
* <ul> * <ul>

View file

@ -21,6 +21,7 @@ import java.io.IOException;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.util.SHA1; import org.jivesoftware.smack.util.SHA1;
import org.jxmpp.jid.Jid;
/** /**
* A collection of utility methods for SOcKS5 messages. * A collection of utility methods for SOcKS5 messages.
@ -38,7 +39,7 @@ class Socks5Utils {
* @param targetJID JID of the target of a SOCKS5 Bytestream * @param targetJID JID of the target of a SOCKS5 Bytestream
* @return SHA-1 digest of the given parameters * @return SHA-1 digest of the given parameters
*/ */
public static String createDigest(String sessionID, String initiatorJID, String targetJID) { public static String createDigest(String sessionID, Jid initiatorJID, Jid targetJID) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
b.append(sessionID).append(initiatorJID).append(targetJID); b.append(sessionID).append(initiatorJID).append(targetJID);
return SHA1.hex(b.toString()); return SHA1.hex(b.toString());

View file

@ -23,6 +23,7 @@ import java.util.List;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
/** /**
* A packet representing part of a SOCKS5 Bytestream negotiation. * A packet representing part of a SOCKS5 Bytestream negotiation.
@ -113,7 +114,7 @@ public class Bytestream extends IQ {
* @param address The internet address of the stream host. * @param address The internet address of the stream host.
* @return The added stream host. * @return The added stream host.
*/ */
public StreamHost addStreamHost(final String JID, final String address) { public StreamHost addStreamHost(final Jid JID, final String address) {
return addStreamHost(JID, address, 0); return addStreamHost(JID, address, 0);
} }
@ -125,7 +126,7 @@ public class Bytestream extends IQ {
* @param port The port on which the remote host is seeking connections. * @param port The port on which the remote host is seeking connections.
* @return The added stream host. * @return The added stream host.
*/ */
public StreamHost addStreamHost(final String JID, final String address, final int port) { public StreamHost addStreamHost(final Jid JID, final String address, final int port) {
StreamHost host = new StreamHost(JID, address, port); StreamHost host = new StreamHost(JID, address, port);
addStreamHost(host); addStreamHost(host);
@ -156,7 +157,7 @@ public class Bytestream extends IQ {
* @param JID The JID of the desired stream host. * @param JID The JID of the desired stream host.
* @return Returns the stream host related to the given JID, or null if there is none. * @return Returns the stream host related to the given JID, or null if there is none.
*/ */
public StreamHost getStreamHost(final String JID) { public StreamHost getStreamHost(final Jid JID) {
if (JID == null) { if (JID == null) {
return null; return null;
} }
@ -184,7 +185,7 @@ public class Bytestream extends IQ {
* *
* @param JID The JID of the used host. * @param JID The JID of the used host.
*/ */
public void setUsedHost(final String JID) { public void setUsedHost(final Jid JID) {
this.usedHost = new StreamHostUsed(JID); this.usedHost = new StreamHostUsed(JID);
} }
@ -215,7 +216,7 @@ public class Bytestream extends IQ {
* *
* @param targetID The JID of the target of the file transfer. * @param targetID The JID of the target of the file transfer.
*/ */
public void setToActivate(final String targetID) { public void setToActivate(final Jid targetID) {
this.toActivate = new Activate(targetID); this.toActivate = new Activate(targetID);
} }
@ -265,13 +266,13 @@ public class Bytestream extends IQ {
public static String ELEMENTNAME = "streamhost"; public static String ELEMENTNAME = "streamhost";
private final String JID; private final Jid JID;
private final String addy; private final String addy;
private final int port; private final int port;
public StreamHost(String jid, String address) { public StreamHost(Jid jid, String address) {
this(jid, address, 0); this(jid, address, 0);
} }
@ -281,7 +282,7 @@ public class Bytestream extends IQ {
* @param JID The JID of the stream host. * @param JID The JID of the stream host.
* @param address The internet address of the stream host. * @param address The internet address of the stream host.
*/ */
public StreamHost(final String JID, final String address, int port) { public StreamHost(final Jid JID, final String address, int port) {
this.JID = JID; this.JID = JID;
this.addy = address; this.addy = address;
this.port = port; this.port = port;
@ -292,7 +293,7 @@ public class Bytestream extends IQ {
* *
* @return Returns the JID of the stream host. * @return Returns the JID of the stream host.
*/ */
public String getJID() { public Jid getJID() {
return JID; return JID;
} }
@ -343,14 +344,14 @@ public class Bytestream extends IQ {
public static String ELEMENTNAME = "streamhost-used"; public static String ELEMENTNAME = "streamhost-used";
private final String JID; private final Jid JID;
/** /**
* Default constructor. * Default constructor.
* *
* @param JID The JID of the selected stream host. * @param JID The JID of the selected stream host.
*/ */
public StreamHostUsed(final String JID) { public StreamHostUsed(final Jid JID) {
this.JID = JID; this.JID = JID;
} }
@ -359,7 +360,7 @@ public class Bytestream extends IQ {
* *
* @return Returns the JID of the selected stream host. * @return Returns the JID of the selected stream host.
*/ */
public String getJID() { public Jid getJID() {
return JID; return JID;
} }
@ -385,14 +386,14 @@ public class Bytestream extends IQ {
public static String ELEMENTNAME = "activate"; public static String ELEMENTNAME = "activate";
private final String target; private final Jid target;
/** /**
* Default constructor specifying the target of the stream. * Default constructor specifying the target of the stream.
* *
* @param target The target of the stream. * @param target The target of the stream.
*/ */
public Activate(final String target) { public Activate(final Jid target) {
this.target = target; this.target = target;
} }
@ -401,7 +402,7 @@ public class Bytestream extends IQ {
* *
* @return Returns the target of the activation. * @return Returns the target of the activation.
*/ */
public String getTarget() { public Jid getTarget() {
return target; return target;
} }

View file

@ -19,7 +19,9 @@ package org.jivesoftware.smackx.bytestreams.socks5.provider;
import java.io.IOException; import java.io.IOException;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -41,7 +43,7 @@ public class BytestreamsProvider extends IQProvider<Bytestream> {
String mode = parser.getAttributeValue("", "mode"); String mode = parser.getAttributeValue("", "mode");
// streamhost // streamhost
String JID = null; Jid JID = null;
String host = null; String host = null;
String port = null; String port = null;
@ -52,15 +54,15 @@ public class BytestreamsProvider extends IQProvider<Bytestream> {
elementName = parser.getName(); elementName = parser.getName();
if (eventType == XmlPullParser.START_TAG) { if (eventType == XmlPullParser.START_TAG) {
if (elementName.equals(Bytestream.StreamHost.ELEMENTNAME)) { if (elementName.equals(Bytestream.StreamHost.ELEMENTNAME)) {
JID = parser.getAttributeValue("", "jid"); JID = ParserUtils.getJidAttribute(parser);
host = parser.getAttributeValue("", "host"); host = parser.getAttributeValue("", "host");
port = parser.getAttributeValue("", "port"); port = parser.getAttributeValue("", "port");
} }
else if (elementName.equals(Bytestream.StreamHostUsed.ELEMENTNAME)) { else if (elementName.equals(Bytestream.StreamHostUsed.ELEMENTNAME)) {
toReturn.setUsedHost(parser.getAttributeValue("", "jid")); toReturn.setUsedHost(ParserUtils.getJidAttribute(parser));
} }
else if (elementName.equals(Bytestream.Activate.ELEMENTNAME)) { else if (elementName.equals(Bytestream.Activate.ELEMENTNAME)) {
toReturn.setToActivate(parser.getAttributeValue("", "jid")); toReturn.setToActivate(ParserUtils.getJidAttribute(parser));
} }
} }
else if (eventType == XmlPullParser.END_TAG) { else if (eventType == XmlPullParser.END_TAG) {

View file

@ -45,6 +45,8 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.cache.LruCache; import org.jxmpp.util.cache.LruCache;
import java.util.Comparator; import java.util.Comparator;
@ -107,7 +109,7 @@ public class EntityCapsManager extends Manager {
* link-local connection the key is formed as user@host (no resource) In * link-local connection the key is formed as user@host (no resource) In
* case of a server or component the key is formed as domain * case of a server or component the key is formed as domain
*/ */
private static final LruCache<String, NodeVerHash> JID_TO_NODEVER_CACHE = new LruCache<String, NodeVerHash>(10000); private static final LruCache<Jid, NodeVerHash> JID_TO_NODEVER_CACHE = new LruCache<>(10000);
static { static {
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
@ -166,7 +168,7 @@ public class EntityCapsManager extends Manager {
} }
} }
public static NodeVerHash getNodeVerHashByJid(String jid) { public static NodeVerHash getNodeVerHashByJid(Jid jid) {
return JID_TO_NODEVER_CACHE.get(jid); return JID_TO_NODEVER_CACHE.get(jid);
} }
@ -179,7 +181,7 @@ public class EntityCapsManager extends Manager {
* user name (Full JID) * user name (Full JID)
* @return the discovered info * @return the discovered info
*/ */
public static DiscoverInfo getDiscoverInfoByUser(String user) { public static DiscoverInfo getDiscoverInfoByUser(Jid user) {
NodeVerHash nvh = JID_TO_NODEVER_CACHE.get(user); NodeVerHash nvh = JID_TO_NODEVER_CACHE.get(user);
if (nvh == null) if (nvh == null)
return null; return null;
@ -242,7 +244,7 @@ public class EntityCapsManager extends Manager {
CAPS_CACHE.clear(); CAPS_CACHE.clear();
} }
private static void addCapsExtensionInfo(String from, CapsExtension capsExtension) { private static void addCapsExtensionInfo(Jid from, CapsExtension capsExtension) {
String capsExtensionHash = capsExtension.getHash(); String capsExtensionHash = capsExtension.getHash();
String hashInUppercase = capsExtensionHash.toUpperCase(Locale.US); String hashInUppercase = capsExtensionHash.toUpperCase(Locale.US);
// SUPPORTED_HASHES uses the format of MessageDigest, which is uppercase, e.g. "SHA-1" instead of "sha-1" // SUPPORTED_HASHES uses the format of MessageDigest, which is uppercase, e.g. "SHA-1" instead of "sha-1"
@ -300,7 +302,7 @@ public class EntityCapsManager extends Manager {
if (capsExtension == null) { if (capsExtension == null) {
return; return;
} }
String from = connection.getServiceName(); DomainBareJid from = connection.getServiceName();
addCapsExtensionInfo(from, capsExtension); addCapsExtensionInfo(from, capsExtension);
} }
}); });
@ -320,7 +322,7 @@ public class EntityCapsManager extends Manager {
return; return;
CapsExtension capsExtension = CapsExtension.from(packet); CapsExtension capsExtension = CapsExtension.from(packet);
String from = packet.getFrom(); Jid from = packet.getFrom();
addCapsExtensionInfo(from, capsExtension); addCapsExtensionInfo(from, capsExtension);
} }
@ -331,7 +333,7 @@ public class EntityCapsManager extends Manager {
public void processPacket(Stanza packet) { public void processPacket(Stanza packet) {
// always remove the JID from the map, even if entityCaps are // always remove the JID from the map, even if entityCaps are
// disabled // disabled
String from = packet.getFrom(); Jid from = packet.getFrom();
JID_TO_NODEVER_CACHE.remove(from); JID_TO_NODEVER_CACHE.remove(from);
} }
}, PRESENCES_WITHOUT_CAPS); }, PRESENCES_WITHOUT_CAPS);
@ -436,7 +438,7 @@ public class EntityCapsManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean areEntityCapsSupported(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean areEntityCapsSupported(Jid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return sdm.supportsFeature(jid, NAMESPACE); return sdm.supportsFeature(jid, NAMESPACE);
} }

View file

@ -22,6 +22,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.commands.packet.AdHocCommandData; import org.jivesoftware.smackx.commands.packet.AdHocCommandData;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.Jid;
import java.util.List; import java.util.List;
@ -146,7 +147,7 @@ public abstract class AdHocCommand {
* *
* @return the owner JID. * @return the owner JID.
*/ */
public abstract String getOwnerJID(); public abstract Jid getOwnerJID();
/** /**
* Returns the notes that the command has at the current stage. * Returns the notes that the command has at the current stage.

View file

@ -48,6 +48,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.Jid;
/** /**
* An AdHocCommandManager is responsible for keeping the list of available * An AdHocCommandManager is responsible for keeping the list of available
@ -254,7 +255,7 @@ public class AdHocCommandManager extends Manager {
* @throws SmackException if there was no response from the server. * @throws SmackException if there was no response from the server.
* @throws InterruptedException * @throws InterruptedException
*/ */
public DiscoverItems discoverCommands(String jid) throws XMPPException, SmackException, InterruptedException { public DiscoverItems discoverCommands(Jid jid) throws XMPPException, SmackException, InterruptedException {
return serviceDiscoveryManager.discoverItems(jid, NAMESPACE); return serviceDiscoveryManager.discoverItems(jid, NAMESPACE);
} }
@ -266,7 +267,7 @@ public class AdHocCommandManager extends Manager {
* @throws SmackException if there was no response from the server. * @throws SmackException if there was no response from the server.
* @throws InterruptedException * @throws InterruptedException
*/ */
public void publishCommands(String jid) throws XMPPException, SmackException, InterruptedException { public void publishCommands(Jid jid) throws XMPPException, SmackException, InterruptedException {
// Collects the commands to publish as items // Collects the commands to publish as items
DiscoverItems discoverItems = new DiscoverItems(); DiscoverItems discoverItems = new DiscoverItems();
Collection<AdHocCommandInfo> xCommandsList = getRegisteredCommands(); Collection<AdHocCommandInfo> xCommandsList = getRegisteredCommands();
@ -291,7 +292,7 @@ public class AdHocCommandManager extends Manager {
* @param node the identifier of the command * @param node the identifier of the command
* @return a local instance equivalent to the remote command. * @return a local instance equivalent to the remote command.
*/ */
public RemoteCommand getRemoteCommand(String jid, String node) { public RemoteCommand getRemoteCommand(Jid jid, String node) {
return new RemoteCommand(connection(), node, jid); return new RemoteCommand(connection(), node, jid);
} }
@ -652,10 +653,10 @@ public class AdHocCommandManager extends Manager {
private String node; private String node;
private String name; private String name;
private String ownerJID; private final Jid ownerJID;
private LocalCommandFactory factory; private LocalCommandFactory factory;
public AdHocCommandInfo(String node, String name, String ownerJID, public AdHocCommandInfo(String node, String name, Jid ownerJID,
LocalCommandFactory factory) LocalCommandFactory factory)
{ {
this.node = node; this.node = node;
@ -678,7 +679,7 @@ public class AdHocCommandManager extends Manager {
return node; return node;
} }
public String getOwnerJID() { public Jid getOwnerJID() {
return ownerJID; return ownerJID;
} }
} }

View file

@ -18,6 +18,7 @@
package org.jivesoftware.smackx.commands; package org.jivesoftware.smackx.commands;
import org.jivesoftware.smackx.commands.packet.AdHocCommandData; import org.jivesoftware.smackx.commands.packet.AdHocCommandData;
import org.jxmpp.jid.Jid;
/** /**
* Represents a command that can be executed locally from a remote location. This * Represents a command that can be executed locally from a remote location. This
@ -52,7 +53,7 @@ public abstract class LocalCommand extends AdHocCommand {
/** /**
* The full JID of the host of the command. * The full JID of the host of the command.
*/ */
private String ownerJID; private Jid ownerJID;
/** /**
* The number of the current stage. * The number of the current stage.
@ -91,12 +92,12 @@ public abstract class LocalCommand extends AdHocCommand {
* *
* @param ownerJID the JID of the owner. * @param ownerJID the JID of the owner.
*/ */
public void setOwnerJID(String ownerJID) { public void setOwnerJID(Jid ownerJID) {
this.ownerJID = ownerJID; this.ownerJID = ownerJID;
} }
@Override @Override
public String getOwnerJID() { public Jid getOwnerJID() {
return ownerJID; return ownerJID;
} }
@ -128,7 +129,7 @@ public abstract class LocalCommand extends AdHocCommand {
* @param jid the JID to check permissions on. * @param jid the JID to check permissions on.
* @return true if the user has permission to execute this action. * @return true if the user has permission to execute this action.
*/ */
public abstract boolean hasPermission(String jid); public abstract boolean hasPermission(Jid jid);
/** /**
* Returns the currently executing stage number. The first stage number is * Returns the currently executing stage number. The first stage number is

View file

@ -23,6 +23,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.commands.packet.AdHocCommandData; import org.jivesoftware.smackx.commands.packet.AdHocCommandData;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.Jid;
/** /**
* Represents a command that is in a remote location. Invoking one of the * Represents a command that is in a remote location. Invoking one of the
@ -48,7 +49,7 @@ public class RemoteCommand extends AdHocCommand {
/** /**
* The full JID of the command host * The full JID of the command host
*/ */
private String jid; private Jid jid;
/** /**
* The session ID of this execution. * The session ID of this execution.
@ -64,7 +65,7 @@ public class RemoteCommand extends AdHocCommand {
* @param node the identifier of the command. * @param node the identifier of the command.
* @param jid the JID of the host. * @param jid the JID of the host.
*/ */
protected RemoteCommand(XMPPConnection connection, String node, String jid) { protected RemoteCommand(XMPPConnection connection, String node, Jid jid) {
super(); super();
this.connection = connection; this.connection = connection;
this.jid = jid; this.jid = jid;
@ -150,7 +151,7 @@ public class RemoteCommand extends AdHocCommand {
} }
@Override @Override
public String getOwnerJID() { public Jid getOwnerJID() {
return jid; return jid;
} }
} }

View file

@ -24,6 +24,7 @@ import org.jivesoftware.smackx.commands.AdHocCommand.Action;
import org.jivesoftware.smackx.commands.AdHocCommand.SpecificErrorCondition; import org.jivesoftware.smackx.commands.AdHocCommand.SpecificErrorCondition;
import org.jivesoftware.smackx.commands.AdHocCommandNote; import org.jivesoftware.smackx.commands.AdHocCommandNote;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.Jid;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -39,7 +40,7 @@ public class AdHocCommandData extends IQ {
public static final String NAMESPACE = "http://jabber.org/protocol/commands"; public static final String NAMESPACE = "http://jabber.org/protocol/commands";
/* JID of the command host */ /* JID of the command host */
private String id; private Jid id;
/* Command name */ /* Command name */
private String name; private String name;
@ -114,11 +115,11 @@ public class AdHocCommandData extends IQ {
* *
* @return the JID of the command host. * @return the JID of the command host.
*/ */
public String getId() { public Jid getId() {
return id; return id;
} }
public void setId(String id) { public void setId(Jid id) {
this.id = id; this.id = id;
} }

View file

@ -34,6 +34,8 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.cache.Cache; import org.jxmpp.util.cache.Cache;
import org.jxmpp.util.cache.ExpirationCache; import org.jxmpp.util.cache.ExpirationCache;
@ -477,7 +479,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public DiscoverInfo discoverInfo(String entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public DiscoverInfo discoverInfo(Jid entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
if (entityID == null) if (entityID == null)
return discoverInfo(null, null); return discoverInfo(null, null);
@ -523,7 +525,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public DiscoverInfo discoverInfo(String entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public DiscoverInfo discoverInfo(Jid entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
// Discover the entity's info // Discover the entity's info
DiscoverInfo disco = new DiscoverInfo(); DiscoverInfo disco = new DiscoverInfo();
disco.setType(IQ.Type.get); disco.setType(IQ.Type.get);
@ -545,7 +547,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public DiscoverItems discoverItems(String entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public DiscoverItems discoverItems(Jid entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return discoverItems(entityID, null); return discoverItems(entityID, null);
} }
@ -562,7 +564,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public DiscoverItems discoverItems(String entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public DiscoverItems discoverItems(Jid entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
// Discover the entity's items // Discover the entity's items
DiscoverItems disco = new DiscoverItems(); DiscoverItems disco = new DiscoverItems();
disco.setType(IQ.Type.get); disco.setType(IQ.Type.get);
@ -586,7 +588,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean canPublishItems(String entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean canPublishItems(Jid entityID) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
DiscoverInfo info = discoverInfo(entityID); DiscoverInfo info = discoverInfo(entityID);
return canPublishItems(info); return canPublishItems(info);
} }
@ -617,7 +619,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void publishItems(String entityID, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public void publishItems(Jid entityID, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
publishItems(entityID, null, discoverItems); publishItems(entityID, null, discoverItems);
} }
@ -635,7 +637,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void publishItems(String entityID, String node, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException public void publishItems(Jid entityID, String node, DiscoverItems discoverItems) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
{ {
discoverItems.setType(IQ.Type.set); discoverItems.setType(IQ.Type.set);
discoverItems.setTo(entityID); discoverItems.setTo(entityID);
@ -671,7 +673,7 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean supportsFeature(String jid, String feature) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean supportsFeature(Jid jid, String feature) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
DiscoverInfo result = discoverInfo(jid); DiscoverInfo result = discoverInfo(jid);
return result.containsFeature(feature); return result.containsFeature(feature);
} }
@ -680,7 +682,7 @@ public class ServiceDiscoveryManager extends Manager {
* Create a cache to hold the 25 most recently lookup services for a given feature for a period * Create a cache to hold the 25 most recently lookup services for a given feature for a period
* of 24 hours. * of 24 hours.
*/ */
private Cache<String, List<String>> services = new ExpirationCache<String, List<String>>(25, private Cache<String, List<DomainBareJid>> services = new ExpirationCache<>(25,
24 * 60 * 60 * 1000); 24 * 60 * 60 * 1000);
/** /**
@ -695,17 +697,17 @@ public class ServiceDiscoveryManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<String> findServices(String feature, boolean stopOnFirst, boolean useCache) public List<DomainBareJid> findServices(String feature, boolean stopOnFirst, boolean useCache)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
List<String> serviceAddresses = null; List<DomainBareJid> serviceAddresses = null;
String serviceName = connection().getServiceName(); DomainBareJid serviceName = connection().getServiceName();
if (useCache) { if (useCache) {
serviceAddresses = (List<String>) services.get(feature); serviceAddresses = services.get(feature);
if (serviceAddresses != null) { if (serviceAddresses != null) {
return serviceAddresses; return serviceAddresses;
} }
} }
serviceAddresses = new LinkedList<String>(); serviceAddresses = new LinkedList<>();
// Send the disco packet to the server itself // Send the disco packet to the server itself
DiscoverInfo info; DiscoverInfo info;
try { try {
@ -748,7 +750,7 @@ public class ServiceDiscoveryManager extends Manager {
continue; continue;
} }
if (info.containsFeature(feature)) { if (info.containsFeature(feature)) {
serviceAddresses.add(item.getEntityID()); serviceAddresses.add(item.getEntityID().asDomainBareJid());
if (stopOnFirst) { if (stopOnFirst) {
break; break;
} }

View file

@ -18,6 +18,7 @@ package org.jivesoftware.smackx.disco.packet;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -134,7 +135,7 @@ public class DiscoverItems extends IQ {
*/ */
public static final String REMOVE_ACTION = "remove"; public static final String REMOVE_ACTION = "remove";
private String entityID; private final Jid entityID;
private String name; private String name;
private String node; private String node;
private String action; private String action;
@ -144,7 +145,7 @@ public class DiscoverItems extends IQ {
* *
* @param entityID the id of the entity that contains the item * @param entityID the id of the entity that contains the item
*/ */
public Item(String entityID) { public Item(Jid entityID) {
this.entityID = entityID; this.entityID = entityID;
} }
@ -153,7 +154,7 @@ public class DiscoverItems extends IQ {
* *
* @return the entity's ID. * @return the entity's ID.
*/ */
public String getEntityID() { public Jid getEntityID() {
return entityID; return entityID;
} }

View file

@ -20,7 +20,9 @@ package org.jivesoftware.smackx.disco.provider;
import java.io.IOException; import java.io.IOException;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -37,7 +39,7 @@ public class DiscoverItemsProvider extends IQProvider<DiscoverItems> {
DiscoverItems discoverItems = new DiscoverItems(); DiscoverItems discoverItems = new DiscoverItems();
boolean done = false; boolean done = false;
DiscoverItems.Item item; DiscoverItems.Item item;
String jid = ""; Jid jid = null;
String name = ""; String name = "";
String action = ""; String action = "";
String node = ""; String node = "";
@ -47,7 +49,7 @@ public class DiscoverItemsProvider extends IQProvider<DiscoverItems> {
if (eventType == XmlPullParser.START_TAG && "item".equals(parser.getName())) { if (eventType == XmlPullParser.START_TAG && "item".equals(parser.getName())) {
// Initialize the variables from the parsed XML // Initialize the variables from the parsed XML
jid = parser.getAttributeValue("", "jid"); jid = ParserUtils.getJidAttribute(parser);
name = parser.getAttributeValue("", "name"); name = parser.getAttributeValue("", "name");
node = parser.getAttributeValue("", "node"); node = parser.getAttributeValue("", "node");
action = parser.getAttributeValue("", "action"); action = parser.getAttributeValue("", "action");

View file

@ -39,6 +39,7 @@ import org.jivesoftware.smack.filter.OrFilter;
import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jxmpp.jid.Jid;
/** /**
@ -61,7 +62,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
this.connection = connection; this.connection = connection;
} }
public PacketFilter getInitiationPacketFilter(String from, String streamID) { public PacketFilter getInitiationPacketFilter(Jid from, String streamID) {
if (primaryFilter == null || secondaryFilter == null) { if (primaryFilter == null || secondaryFilter == null) {
primaryFilter = primaryNegotiator.getInitiationPacketFilter(from, streamID); primaryFilter = primaryNegotiator.getInitiationPacketFilter(from, streamID);
secondaryFilter = secondaryNegotiator.getInitiationPacketFilter(from, streamID); secondaryFilter = secondaryNegotiator.getInitiationPacketFilter(from, streamID);
@ -143,7 +144,7 @@ public class FaultTolerantNegotiator extends StreamNegotiator {
return primaryFilter.accept(streamInitiation) ? primaryNegotiator : secondaryNegotiator; return primaryFilter.accept(streamInitiation) ? primaryNegotiator : secondaryNegotiator;
} }
public OutputStream createOutgoingStream(String streamID, String initiator, String target) public OutputStream createOutgoingStream(String streamID, Jid initiator, Jid target)
throws SmackException, XMPPException, InterruptedException { throws SmackException, XMPPException, InterruptedException {
OutputStream stream; OutputStream stream;
try { try {

View file

@ -20,6 +20,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import org.jxmpp.jid.Jid;
/** /**
* Contains the generic file information and progress related to a particular * Contains the generic file information and progress related to a particular
* file transfer. * file transfer.
@ -35,7 +37,7 @@ public abstract class FileTransfer {
private long fileSize; private long fileSize;
private String peer; private Jid peer;
private Status status = Status.initial; private Status status = Status.initial;
@ -56,7 +58,7 @@ public abstract class FileTransfer {
*/ */
private static final int BUFFER_SIZE = 8192; private static final int BUFFER_SIZE = 8192;
protected FileTransfer(String peer, String streamID, protected FileTransfer(Jid peer, String streamID,
FileTransferNegotiator negotiator) { FileTransferNegotiator negotiator) {
this.peer = peer; this.peer = peer;
this.streamID = streamID; this.streamID = streamID;
@ -106,7 +108,7 @@ public abstract class FileTransfer {
* *
* @return Returns the JID of the peer for this file transfer. * @return Returns the JID of the peer for this file transfer.
*/ */
public String getPeer() { public Jid getPeer() {
return peer; return peer;
} }

View file

@ -24,7 +24,7 @@ import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.FullJid;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -33,7 +33,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* The file transfer manager class handles the sending and recieving of files. * The file transfer manager class handles the sending and recieving of files.
* To send a file invoke the {@link #createOutgoingFileTransfer(String)} method. * To send a file invoke the {@link #createOutgoingFileTransfer(FullJid)} method.
* <p> * <p>
* And to recieve a file add a file transfer listener to the manager. The * And to recieve a file add a file transfer listener to the manager. The
* listener will notify you when there is a new file transfer request. To create * listener will notify you when there is a new file transfer request. To create
@ -117,15 +117,12 @@ public class FileTransferManager extends Manager {
* @return The send file object on which the negotiated transfer can be run. * @return The send file object on which the negotiated transfer can be run.
* @exception IllegalArgumentException if userID is null or not a full JID * @exception IllegalArgumentException if userID is null or not a full JID
*/ */
public OutgoingFileTransfer createOutgoingFileTransfer(String userID) { public OutgoingFileTransfer createOutgoingFileTransfer(FullJid userID) {
if (userID == null) {
throw new IllegalArgumentException("userID was null");
}
// We need to create outgoing file transfers with a full JID since this method will later // We need to create outgoing file transfers with a full JID since this method will later
// use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID // use XEP-0095 to negotiate the stream. This is done with IQ stanzas that need to be addressed to a full JID
// in order to reach an client entity. // in order to reach an client entity.
else if (!XmppStringUtils.isFullJID(userID)) { if (userID == null) {
throw new IllegalArgumentException("The provided user id was not a full JID (i.e. with resource part)"); throw new IllegalArgumentException("userID was null");
} }
return new OutgoingFileTransfer(connection().getUser(), userID, return new OutgoingFileTransfer(connection().getUser(), userID,

View file

@ -42,6 +42,7 @@ import org.jivesoftware.smackx.filetransfer.FileTransferException.NoStreamMethod
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.Jid;
/** /**
* Manages the negotiation of file transfers according to XEP-0096. If a file is * Manages the negotiation of file transfers according to XEP-0096. If a file is
@ -302,7 +303,7 @@ public class FileTransferNegotiator extends Manager {
* @throws NoAcceptableTransferMechanisms * @throws NoAcceptableTransferMechanisms
* @throws InterruptedException * @throws InterruptedException
*/ */
public StreamNegotiator negotiateOutgoingTransfer(final String userID, public StreamNegotiator negotiateOutgoingTransfer(final Jid userID,
final String streamID, final String fileName, final long size, final String streamID, final String fileName, final long size,
final String desc, int responseTimeout) throws XMPPErrorException, NotConnectedException, NoResponseException, NoAcceptableTransferMechanisms, InterruptedException { final String desc, int responseTimeout) throws XMPPErrorException, NotConnectedException, NoResponseException, NoAcceptableTransferMechanisms, InterruptedException {
StreamInitiation si = new StreamInitiation(); StreamInitiation si = new StreamInitiation();

View file

@ -18,6 +18,7 @@ package org.jivesoftware.smackx.filetransfer;
import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jxmpp.jid.Jid;
/** /**
* A request to send a file recieved from another user. * A request to send a file recieved from another user.
@ -88,7 +89,7 @@ public class FileTransferRequest {
* @return Returns the fully-qualified jabber ID of the user that requested * @return Returns the fully-qualified jabber ID of the user that requested
* this file transfer. * this file transfer.
*/ */
public String getRequestor() { public Jid getRequestor() {
return streamInitiation.getFrom(); return streamInitiation.getFrom();
} }

View file

@ -35,6 +35,7 @@ import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamSession;
import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension; import org.jivesoftware.smackx.bytestreams.ibb.packet.DataPacketExtension;
import org.jivesoftware.smackx.bytestreams.ibb.packet.Open; import org.jivesoftware.smackx.bytestreams.ibb.packet.Open;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jxmpp.jid.Jid;
/** /**
* The In-Band Bytestream file transfer method, or IBB for short, transfers the * The In-Band Bytestream file transfer method, or IBB for short, transfers the
@ -62,8 +63,8 @@ public class IBBTransferNegotiator extends StreamNegotiator {
this.manager = InBandBytestreamManager.getByteStreamManager(connection); this.manager = InBandBytestreamManager.getByteStreamManager(connection);
} }
public OutputStream createOutgoingStream(String streamID, String initiator, public OutputStream createOutgoingStream(String streamID, Jid initiator,
String target) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { Jid target) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
InBandBytestreamSession session = this.manager.establishSession(target, streamID); InBandBytestreamSession session = this.manager.establishSession(target, streamID);
session.setCloseBothStreamsEnabled(true); session.setCloseBothStreamsEnabled(true);
return session.getOutputStream(); return session.getOutputStream();
@ -81,7 +82,7 @@ public class IBBTransferNegotiator extends StreamNegotiator {
return negotiateIncomingStream(streamInitiation); return negotiateIncomingStream(streamInitiation);
} }
public PacketFilter getInitiationPacketFilter(String from, String streamID) { public PacketFilter getInitiationPacketFilter(Jid from, String streamID) {
/* /*
* this method is always called prior to #negotiateIncomingStream() so * this method is always called prior to #negotiateIncomingStream() so
* the In-Band Bytestream initiation listener must ignore the next * the In-Band Bytestream initiation listener must ignore the next

View file

@ -30,6 +30,7 @@ import org.jivesoftware.smack.SmackException.IllegalStateChangeException;
import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.packet.XMPPError;
import org.jxmpp.jid.Jid;
/** /**
* Handles the sending of a file to another user. File transfer's in jabber have * Handles the sending of a file to another user. File transfer's in jabber have
@ -70,11 +71,11 @@ public class OutgoingFileTransfer extends FileTransfer {
private OutputStream outputStream; private OutputStream outputStream;
private String initiator; private Jid initiator;
private Thread transferThread; private Thread transferThread;
protected OutgoingFileTransfer(String initiator, String target, protected OutgoingFileTransfer(Jid initiator, Jid target,
String streamID, FileTransferNegotiator transferNegotiator) { String streamID, FileTransferNegotiator transferNegotiator) {
super(target, streamID, transferNegotiator); super(target, streamID, transferNegotiator);
this.initiator = initiator; this.initiator = initiator;

View file

@ -37,6 +37,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest;
import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession;
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jxmpp.jid.Jid;
/** /**
* Negotiates a SOCKS5 Bytestream to be used for file transfers. The implementation is based on the * Negotiates a SOCKS5 Bytestream to be used for file transfers. The implementation is based on the
@ -57,7 +58,7 @@ public class Socks5TransferNegotiator extends StreamNegotiator {
} }
@Override @Override
public OutputStream createOutgoingStream(String streamID, String initiator, String target) throws NoResponseException, SmackException, XMPPException public OutputStream createOutgoingStream(String streamID, Jid initiator, Jid target) throws NoResponseException, SmackException, XMPPException
{ {
try { try {
return this.manager.establishSession(target, streamID).getOutputStream(); return this.manager.establishSession(target, streamID).getOutputStream();
@ -84,7 +85,7 @@ public class Socks5TransferNegotiator extends StreamNegotiator {
} }
@Override @Override
public PacketFilter getInitiationPacketFilter(final String from, String streamID) { public PacketFilter getInitiationPacketFilter(final Jid from, String streamID) {
/* /*
* this method is always called prior to #negotiateIncomingStream() so the SOCKS5 * this method is always called prior to #negotiateIncomingStream() so the SOCKS5
* InitiationListener must ignore the next SOCKS5 Bytestream request with the given session * InitiationListener must ignore the next SOCKS5 Bytestream request with the given session

View file

@ -29,6 +29,7 @@ import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smackx.si.packet.StreamInitiation; import org.jivesoftware.smackx.si.packet.StreamInitiation;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.Jid;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -94,7 +95,7 @@ public abstract class StreamNegotiator {
* @return The <b><i>PacketFilter</b></i> that will return the packet relatable to the stream * @return The <b><i>PacketFilter</b></i> that will return the packet relatable to the stream
* initiation. * initiation.
*/ */
public abstract PacketFilter getInitiationPacketFilter(String from, String streamID); public abstract PacketFilter getInitiationPacketFilter(Jid from, String streamID);
abstract InputStream negotiateIncomingStream(Stanza streamInitiation) throws XMPPErrorException, abstract InputStream negotiateIncomingStream(Stanza streamInitiation) throws XMPPErrorException,
@ -137,7 +138,7 @@ public abstract class StreamNegotiator {
* @throws InterruptedException * @throws InterruptedException
*/ */
public abstract OutputStream createOutgoingStream(String streamID, public abstract OutputStream createOutgoingStream(String streamID,
String initiator, String target) throws XMPPErrorException, NoResponseException, SmackException, XMPPException, InterruptedException; Jid initiator, Jid target) throws XMPPErrorException, NoResponseException, SmackException, XMPPException, InterruptedException;
/** /**
* Returns the XMPP namespace reserved for this particular type of file * Returns the XMPP namespace reserved for this particular type of file

View file

@ -40,6 +40,7 @@ import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.iqlast.packet.LastActivity; import org.jivesoftware.smackx.iqlast.packet.LastActivity;
import org.jxmpp.jid.Jid;
/** /**
* A last activity manager for handling information about the last activity * A last activity manager for handling information about the last activity
@ -233,7 +234,7 @@ public class LastActivityManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public LastActivity getLastActivity(String jid) throws NoResponseException, XMPPErrorException, public LastActivity getLastActivity(Jid jid) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
LastActivity activity = new LastActivity(jid); LastActivity activity = new LastActivity(jid);
return (LastActivity) connection().createPacketCollectorAndSend(activity).nextResultOrThrow(); return (LastActivity) connection().createPacketCollectorAndSend(activity).nextResultOrThrow();
@ -249,7 +250,7 @@ public class LastActivityManager extends Manager {
* @throws NoResponseException * @throws NoResponseException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean isLastActivitySupported(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean isLastActivitySupported(Jid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, LastActivity.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, LastActivity.NAMESPACE);
} }
} }

View file

@ -22,6 +22,7 @@ import java.io.IOException;
import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -47,7 +48,7 @@ public class LastActivity extends IQ {
setType(IQ.Type.get); setType(IQ.Type.get);
} }
public LastActivity(String to) { public LastActivity(Jid to) {
this(); this();
setTo(to); setTo(to);
} }

View file

@ -34,7 +34,6 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.PacketIDFilter; import org.jivesoftware.smack.filter.PacketIDFilter;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.iqregister.packet.Registration; import org.jivesoftware.smackx.iqregister.packet.Registration;
import org.jxmpp.util.XmppStringUtils;
/** /**
* Allows creation and management of accounts on an XMPP server. * Allows creation and management of accounts on an XMPP server.
@ -253,7 +252,7 @@ public class AccountManager extends Manager {
*/ */
public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>();
map.put("username",XmppStringUtils.parseLocalpart(connection().getUser())); map.put("username", connection().getUser().getLocalpart().toString());
map.put("password",newPassword); map.put("password",newPassword);
Registration reg = new Registration(map); Registration reg = new Registration(map);
reg.setType(IQ.Type.set); reg.setType(IQ.Type.set);

View file

@ -35,6 +35,7 @@ import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.iqversion.packet.Version; import org.jivesoftware.smackx.iqversion.packet.Version;
import org.jxmpp.jid.Jid;
/** /**
* A Version Manager that automatically responds to version IQs with a predetermined reply. * A Version Manager that automatically responds to version IQs with a predetermined reply.
@ -123,7 +124,7 @@ public class VersionManager extends Manager {
ourVersion = null; ourVersion = null;
} }
public boolean isSupported(String jid) throws NoResponseException, XMPPErrorException, public boolean isSupported(Jid jid) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid,
Version.NAMESPACE); Version.NAMESPACE);
@ -139,7 +140,7 @@ public class VersionManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public Version getVersion(String jid) throws NoResponseException, XMPPErrorException, public Version getVersion(Jid jid) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
if (!isSupported(jid)) { if (!isSupported(jid)) {
return null; return null;

View file

@ -21,6 +21,7 @@ package org.jivesoftware.smackx.iqversion.packet;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jxmpp.jid.Jid;
/** /**
* A Version IQ packet, which is used by XMPP clients to discover version information * A Version IQ packet, which is used by XMPP clients to discover version information
@ -68,7 +69,7 @@ public class Version extends IQ {
* *
* @param to the jid where to request version from * @param to the jid where to request version from
*/ */
public Version(String to) { public Version(Jid to) {
this(); this();
setTo(to); setTo(to);
} }

View file

@ -18,6 +18,8 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* Represents an affiliation of a user to a given room. The affiliate's information will always have * Represents an affiliation of a user to a given room. The affiliate's information will always have
@ -28,12 +30,12 @@ import org.jivesoftware.smackx.muc.packet.MUCItem;
*/ */
public class Affiliate { public class Affiliate {
// Fields that must have a value // Fields that must have a value
private final String jid; private final Jid jid;
private final MUCAffiliation affiliation; private final MUCAffiliation affiliation;
// Fields that may have a value // Fields that may have a value
private final MUCRole role; private final MUCRole role;
private final String nick; private final Resourcepart nick;
Affiliate(MUCItem item) { Affiliate(MUCItem item) {
this.jid = item.getJid(); this.jid = item.getJid();
@ -47,7 +49,7 @@ public class Affiliate {
* *
* @return the bare JID of the affiliated user. * @return the bare JID of the affiliated user.
*/ */
public String getJid() { public Jid getJid() {
return jid; return jid;
} }
@ -79,7 +81,7 @@ public class Affiliate {
* @return the current nickname of the affiliated user in the room or null if the user is not in * @return the current nickname of the affiliated user in the room or null if the user is not in
* the room. * the room.
*/ */
public String getNick() { public Resourcepart getNick() {
return nick; return nick;
} }
} }

View file

@ -17,6 +17,10 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* Default implementation of the ParticipantStatusListener interface.<p> * Default implementation of the ParticipantStatusListener interface.<p>
* *
@ -28,49 +32,49 @@ package org.jivesoftware.smackx.muc;
*/ */
public class DefaultParticipantStatusListener implements ParticipantStatusListener { public class DefaultParticipantStatusListener implements ParticipantStatusListener {
public void joined(String participant) { public void joined(FullJid participant) {
} }
public void left(String participant) { public void left(FullJid participant) {
} }
public void kicked(String participant, String actor, String reason) { public void kicked(FullJid participant, Jid actor, String reason) {
} }
public void voiceGranted(String participant) { public void voiceGranted(FullJid participant) {
} }
public void voiceRevoked(String participant) { public void voiceRevoked(FullJid participant) {
} }
public void banned(String participant, String actor, String reason) { public void banned(FullJid participant, Jid actor, String reason) {
} }
public void membershipGranted(String participant) { public void membershipGranted(FullJid participant) {
} }
public void membershipRevoked(String participant) { public void membershipRevoked(FullJid participant) {
} }
public void moderatorGranted(String participant) { public void moderatorGranted(FullJid participant) {
} }
public void moderatorRevoked(String participant) { public void moderatorRevoked(FullJid participant) {
} }
public void ownershipGranted(String participant) { public void ownershipGranted(FullJid participant) {
} }
public void ownershipRevoked(String participant) { public void ownershipRevoked(FullJid participant) {
} }
public void adminGranted(String participant) { public void adminGranted(FullJid participant) {
} }
public void adminRevoked(String participant) { public void adminRevoked(FullJid participant) {
} }
public void nicknameChanged(String participant, String newNickname) { public void nicknameChanged(FullJid participant, Resourcepart newNickname) {
} }
} }

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jxmpp.jid.Jid;
/** /**
* Default implementation of the UserStatusListener interface.<p> * Default implementation of the UserStatusListener interface.<p>
* *
@ -28,7 +30,7 @@ package org.jivesoftware.smackx.muc;
*/ */
public class DefaultUserStatusListener implements UserStatusListener { public class DefaultUserStatusListener implements UserStatusListener {
public void kicked(String actor, String reason) { public void kicked(Jid actor, String reason) {
} }
public void voiceGranted() { public void voiceGranted() {
@ -37,7 +39,7 @@ public class DefaultUserStatusListener implements UserStatusListener {
public void voiceRevoked() { public void voiceRevoked() {
} }
public void banned(String actor, String reason) { public void banned(Jid actor, String reason) {
} }
public void membershipGranted() { public void membershipGranted() {

View file

@ -17,21 +17,22 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jxmpp.jid.Jid;
/** /**
* Hosted rooms by a chat service may be discovered if they are configured to appear in the room * Hosted rooms by a chat service may be discovered if they are configured to appear in the room
* directory . The information that may be discovered is the XMPP address of the room and the room * directory . The information that may be discovered is the XMPP address of the room and the room
* name. The address of the room may be used for obtaining more detailed information * name. The address of the room may be used for obtaining more detailed information
* {@link org.jivesoftware.smackx.muc.MultiUserChatManager#getRoomInfo(String)} * {@link org.jivesoftware.smackx.muc.MultiUserChatManager#getRoomInfo(org.jxmpp.jid.BareJid)}
* or could be used for joining the room * or could be used for joining the room
* {@link org.jivesoftware.smackx.muc.MultiUserChatManager#getMultiUserChat(String)} * {@link org.jivesoftware.smackx.muc.MultiUserChatManager#getMultiUserChat(org.jxmpp.jid.BareJid)}
* and {@link org.jivesoftware.smackx.muc.MultiUserChat#join(String)}. * and {@link org.jivesoftware.smackx.muc.MultiUserChat#join(org.jxmpp.jid.parts.Resourcepart)}.
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public class HostedRoom { public class HostedRoom {
private final String jid; private final Jid jid;
private final String name; private final String name;
@ -46,7 +47,7 @@ public class HostedRoom {
* *
* @return the XMPP address of the hosted room by the chat service. * @return the XMPP address of the hosted room by the chat service.
*/ */
public String getJid() { public Jid getJid() {
return jid; return jid;
} }

View file

@ -19,9 +19,7 @@ package org.jivesoftware.smackx.muc;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -69,9 +67,15 @@ import org.jivesoftware.smackx.muc.packet.MUCUser.Status;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.JidWithLocalpart;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* A MultiUserChat room (XEP-45), created with {@link MultiUserChatManager#getMultiUserChat(String)}. * A MultiUserChat room (XEP-45), created with {@link MultiUserChatManager#getMultiUserChat(BareJid)}.
* <p> * <p>
* A MultiUserChat is a conversation that takes place among many users in a virtual * A MultiUserChat is a conversation that takes place among many users in a virtual
* room. A room could have many occupants with different affiliation and roles. * room. A room could have many occupants with different affiliation and roles.
@ -91,9 +95,9 @@ public class MultiUserChat {
private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName()); private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName());
private final XMPPConnection connection; private final XMPPConnection connection;
private final String room; private final BareJid room;
private final MultiUserChatManager multiUserChatManager; private final MultiUserChatManager multiUserChatManager;
private final Map<String, Presence> occupantsMap = new ConcurrentHashMap<String, Presence>(); private final Map<FullJid, Presence> occupantsMap = new ConcurrentHashMap<>();
private final Set<InvitationRejectionListener> invitationRejectionListeners = new CopyOnWriteArraySet<InvitationRejectionListener>(); private final Set<InvitationRejectionListener> invitationRejectionListeners = new CopyOnWriteArraySet<InvitationRejectionListener>();
private final Set<SubjectUpdatedListener> subjectUpdatedListeners = new CopyOnWriteArraySet<SubjectUpdatedListener>(); private final Set<SubjectUpdatedListener> subjectUpdatedListeners = new CopyOnWriteArraySet<SubjectUpdatedListener>();
@ -122,13 +126,13 @@ public class MultiUserChat {
private final PacketListener declinesListener; private final PacketListener declinesListener;
private String subject; private String subject;
private String nickname = null; private Resourcepart nickname;
private boolean joined = false; private boolean joined = false;
private PacketCollector messageCollector; private PacketCollector messageCollector;
MultiUserChat(XMPPConnection connection, String room, MultiUserChatManager multiUserChatManager) { MultiUserChat(XMPPConnection connection, BareJid room, MultiUserChatManager multiUserChatManager) {
this.connection = connection; this.connection = connection;
this.room = room.toLowerCase(Locale.US); this.room = room;
this.multiUserChatManager = multiUserChatManager; this.multiUserChatManager = multiUserChatManager;
fromRoomFilter = FromMatchesFilter.create(room); fromRoomFilter = FromMatchesFilter.create(room);
@ -148,11 +152,16 @@ public class MultiUserChat {
subjectListener = new PacketListener() { subjectListener = new PacketListener() {
public void processPacket(Stanza packet) { public void processPacket(Stanza packet) {
Message msg = (Message) packet; Message msg = (Message) packet;
FullJid from = msg.getFrom().asFullJidIfPossible();
if (from == null) {
LOGGER.warning("Message subject not changed by a full JID: " + msg.getFrom());
return;
}
// Update the room subject // Update the room subject
subject = msg.getSubject(); subject = msg.getSubject();
// Fire event for subject updated listeners // Fire event for subject updated listeners
for (SubjectUpdatedListener listener : subjectUpdatedListeners) { for (SubjectUpdatedListener listener : subjectUpdatedListeners) {
listener.subjectUpdated(subject, msg.getFrom()); listener.subjectUpdated(subject, from);
} }
} }
}; };
@ -161,7 +170,11 @@ public class MultiUserChat {
presenceListener = new PacketListener() { presenceListener = new PacketListener() {
public void processPacket(Stanza packet) { public void processPacket(Stanza packet) {
Presence presence = (Presence) packet; Presence presence = (Presence) packet;
String from = presence.getFrom(); final FullJid from = presence.getFrom().asFullJidIfPossible();
if (from == null) {
LOGGER.warning("Presence not from a full JID: " + presence.getFrom());
return;
}
String myRoomJID = MultiUserChat.this.room + "/" + nickname; String myRoomJID = MultiUserChat.this.room + "/" + nickname;
boolean isUserStatusModification = presence.getFrom().equals(myRoomJID); boolean isUserStatusModification = presence.getFrom().equals(myRoomJID);
switch (presence.getType()) { switch (presence.getType()) {
@ -254,7 +267,7 @@ public class MultiUserChat {
* *
* @return the multi user chat room name. * @return the multi user chat room name.
*/ */
public String getRoom() { public BareJid getRoom() {
return room; return room;
} }
@ -272,14 +285,15 @@ public class MultiUserChat {
* @throws InterruptedException * @throws InterruptedException
* @see <a href="http://xmpp.org/extensions/xep-0045.html#enter">XEP-45 7.2 Entering a Room</a> * @see <a href="http://xmpp.org/extensions/xep-0045.html#enter">XEP-45 7.2 Entering a Room</a>
*/ */
private Presence enter(String nickname, String password, DiscussionHistory history, private Presence enter(Resourcepart nickname, String password, DiscussionHistory history,
long timeout) throws NotConnectedException, NoResponseException, long timeout) throws NotConnectedException, NoResponseException,
XMPPErrorException, InterruptedException { XMPPErrorException, InterruptedException {
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank."); StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
// We enter a room by sending a presence packet where the "to" // We enter a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname" // field is in the form "roomName@service/nickname"
Presence joinPresence = new Presence(Presence.Type.available); Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setTo(room + "/" + nickname); final FullJid jid = JidCreate.fullFrom(room, nickname);
joinPresence.setTo(jid);
// Indicate the the client supports MUC // Indicate the the client supports MUC
MUCInitialPresence mucInitialPresence = new MUCInitialPresence(); MUCInitialPresence mucInitialPresence = new MUCInitialPresence();
@ -292,8 +306,7 @@ public class MultiUserChat {
joinPresence.addExtension(mucInitialPresence); joinPresence.addExtension(mucInitialPresence);
// Wait for a presence packet back from the server. // Wait for a presence packet back from the server.
PacketFilter responseFilter = new AndFilter(FromMatchesFilter.createFull(room + "/" PacketFilter responseFilter = new AndFilter(FromMatchesFilter.createFull(jid), new PacketTypeFilter(Presence.class));
+ nickname), new PacketTypeFilter(Presence.class));
// Setup the messageListeners and presenceListeners *before* the join presence is send. // Setup the messageListeners and presenceListeners *before* the join presence is send.
connection.addSyncPacketListener(messageListener, fromRoomGroupchatFilter); connection.addSyncPacketListener(messageListener, fromRoomGroupchatFilter);
@ -348,7 +361,7 @@ public class MultiUserChat {
* server, e.g. because the room already existed. * server, e.g. because the room already existed.
* @throws InterruptedException * @throws InterruptedException
*/ */
public synchronized void create(String nickname) throws NoResponseException, XMPPErrorException, SmackException, InterruptedException { public synchronized void create(Resourcepart nickname) throws NoResponseException, XMPPErrorException, SmackException, InterruptedException {
if (joined) { if (joined) {
throw new IllegalStateException("Creation failed - User already joined the room."); throw new IllegalStateException("Creation failed - User already joined the room.");
} }
@ -363,7 +376,7 @@ public class MultiUserChat {
} }
/** /**
* Same as {@link #createOrJoin(String, String, DiscussionHistory, long)}, but without a password, specifying a * Same as {@link #createOrJoin(Resourcepart, String, DiscussionHistory, long)}, but without a password, specifying a
* discussion history and using the connections default reply timeout. * discussion history and using the connections default reply timeout.
* *
* @param nickname * @param nickname
@ -372,15 +385,15 @@ public class MultiUserChat {
* @throws XMPPErrorException * @throws XMPPErrorException
* @throws SmackException * @throws SmackException
* @throws InterruptedException * @throws InterruptedException
* @see #createOrJoin(String, String, DiscussionHistory, long) * @see #createOrJoin(Resourcepart, String, DiscussionHistory, long)
*/ */
public synchronized boolean createOrJoin(String nickname) throws NoResponseException, XMPPErrorException, public synchronized boolean createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
SmackException, InterruptedException { SmackException, InterruptedException {
return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout()); return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout());
} }
/** /**
* Like {@link #create(String)}, but will return true if the room creation was acknowledged by * Like {@link #create(Resourcepart)}, but will return true if the room creation was acknowledged by
* the service (with an 201 status code). It's up to the caller to decide, based on the return * the service (with an 201 status code). It's up to the caller to decide, based on the return
* value, if he needs to continue sending the room configuration. If false is returned, the room * value, if he needs to continue sending the room configuration. If false is returned, the room
* already existed and the user is able to join right away, without sending a form. * already existed and the user is able to join right away, without sending a form.
@ -395,7 +408,7 @@ public class MultiUserChat {
* @throws NoResponseException if there was no response from the server. * @throws NoResponseException if there was no response from the server.
* @throws InterruptedException * @throws InterruptedException
*/ */
public synchronized boolean createOrJoin(String nickname, String password, DiscussionHistory history, long timeout) public synchronized boolean createOrJoin(Resourcepart nickname, String password, DiscussionHistory history, long timeout)
throws NoResponseException, XMPPErrorException, SmackException, InterruptedException { throws NoResponseException, XMPPErrorException, SmackException, InterruptedException {
if (joined) { if (joined) {
throw new IllegalStateException("Creation failed - User already joined the room."); throw new IllegalStateException("Creation failed - User already joined the room.");
@ -431,7 +444,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void join(String nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public void join(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
join(nickname, null, null, connection.getPacketReplyTimeout()); join(nickname, null, null, connection.getPacketReplyTimeout());
} }
@ -456,7 +469,7 @@ public class MultiUserChat {
* @throws SmackException if there was no response from the server. * @throws SmackException if there was no response from the server.
* @throws InterruptedException * @throws InterruptedException
*/ */
public void join(String nickname, String password) throws XMPPErrorException, SmackException, InterruptedException { public void join(Resourcepart nickname, String password) throws XMPPErrorException, SmackException, InterruptedException {
join(nickname, password, null, connection.getPacketReplyTimeout()); join(nickname, password, null, connection.getPacketReplyTimeout());
} }
@ -489,7 +502,7 @@ public class MultiUserChat {
* @throws InterruptedException * @throws InterruptedException
*/ */
public synchronized void join( public synchronized void join(
String nickname, Resourcepart nickname,
String password, String password,
DiscussionHistory history, DiscussionHistory history,
long timeout) long timeout)
@ -504,7 +517,7 @@ public class MultiUserChat {
/** /**
* Returns true if currently in the multi user chat (after calling the {@link * Returns true if currently in the multi user chat (after calling the {@link
* #join(String)} method). * #join(Resourcepart)} method).
* *
* @return true if currently in the multi user chat room. * @return true if currently in the multi user chat room.
*/ */
@ -525,7 +538,7 @@ public class MultiUserChat {
// We leave a room by sending a presence packet where the "to" // We leave a room by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname" // field is in the form "roomName@service/nickname"
Presence leavePresence = new Presence(Presence.Type.unavailable); Presence leavePresence = new Presence(Presence.Type.unavailable);
leavePresence.setTo(room + "/" + nickname); leavePresence.setTo(JidCreate.fullFrom(room, nickname));
connection.sendPacket(leavePresence); connection.sendPacket(leavePresence);
// Reset occupant information. // Reset occupant information.
occupantsMap.clear(); occupantsMap.clear();
@ -841,7 +854,7 @@ public class MultiUserChat {
* *
* @return the nickname currently being used. * @return the nickname currently being used.
*/ */
public String getNickname() { public Resourcepart getNickname() {
return nickname; return nickname;
} }
@ -858,23 +871,24 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void changeNickname(String nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public void changeNickname(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank."); StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
// Check that we already have joined the room before attempting to change the // Check that we already have joined the room before attempting to change the
// nickname. // nickname.
if (!joined) { if (!joined) {
throw new IllegalStateException("Must be logged into the room to change nickname."); throw new IllegalStateException("Must be logged into the room to change nickname.");
} }
final FullJid jid = JidCreate.fullFrom(room, nickname);
// We change the nickname by sending a presence packet where the "to" // We change the nickname by sending a presence packet where the "to"
// field is in the form "roomName@service/nickname" // field is in the form "roomName@service/nickname"
// We don't have to signal the MUC support again // We don't have to signal the MUC support again
Presence joinPresence = new Presence(Presence.Type.available); Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setTo(room + "/" + nickname); joinPresence.setTo(jid);
// Wait for a presence packet back from the server. // Wait for a presence packet back from the server.
PacketFilter responseFilter = PacketFilter responseFilter =
new AndFilter( new AndFilter(
FromMatchesFilter.createFull(room + "/" + nickname), FromMatchesFilter.createFull(jid),
new PacketTypeFilter(Presence.class)); new PacketTypeFilter(Presence.class));
PacketCollector response = connection.createPacketCollectorAndSend(responseFilter, joinPresence); PacketCollector response = connection.createPacketCollectorAndSend(responseFilter, joinPresence);
// Wait up to a certain number of seconds for a reply. If there is a negative reply, an // Wait up to a certain number of seconds for a reply. If there is a negative reply, an
@ -907,7 +921,7 @@ public class MultiUserChat {
Presence joinPresence = new Presence(Presence.Type.available); Presence joinPresence = new Presence(Presence.Type.available);
joinPresence.setStatus(status); joinPresence.setStatus(status);
joinPresence.setMode(mode); joinPresence.setMode(mode);
joinPresence.setTo(room + "/" + nickname); joinPresence.setTo(JidCreate.fullFrom(room, nickname));
// Send join packet. // Send join packet.
connection.sendPacket(joinPresence); connection.sendPacket(joinPresence);
@ -934,7 +948,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void kickParticipant(String nickname, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void kickParticipant(Resourcepart nickname, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nickname, MUCRole.none, reason); changeRole(nickname, MUCRole.none, reason);
} }
@ -976,7 +990,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantVoice(Collection<String> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantVoice(Collection<Resourcepart> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nicknames, MUCRole.participant); changeRole(nicknames, MUCRole.participant);
} }
@ -994,7 +1008,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantVoice(String nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantVoice(Resourcepart nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nickname, MUCRole.participant, null); changeRole(nickname, MUCRole.participant, null);
} }
@ -1012,7 +1026,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeVoice(Collection<String> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeVoice(Collection<Resourcepart> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nicknames, MUCRole.visitor); changeRole(nicknames, MUCRole.visitor);
} }
@ -1030,7 +1044,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeVoice(String nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeVoice(Resourcepart nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nickname, MUCRole.visitor, null); changeRole(nickname, MUCRole.visitor, null);
} }
@ -1049,7 +1063,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void banUsers(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void banUsers(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.outcast); changeAffiliationByAdmin(jids, MUCAffiliation.outcast);
} }
@ -1069,7 +1083,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void banUser(String jid, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void banUser(Jid jid, String reason) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.outcast, reason); changeAffiliationByAdmin(jid, MUCAffiliation.outcast, reason);
} }
@ -1084,7 +1098,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantMembership(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantMembership(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.member); changeAffiliationByAdmin(jids, MUCAffiliation.member);
} }
@ -1099,7 +1113,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantMembership(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantMembership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.member, null); changeAffiliationByAdmin(jid, MUCAffiliation.member, null);
} }
@ -1115,7 +1129,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeMembership(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeMembership(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.none); changeAffiliationByAdmin(jids, MUCAffiliation.none);
} }
@ -1131,7 +1145,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeMembership(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeMembership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.none, null); changeAffiliationByAdmin(jid, MUCAffiliation.none, null);
} }
@ -1146,7 +1160,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantModerator(Collection<String> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantModerator(Collection<Resourcepart> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nicknames, MUCRole.moderator); changeRole(nicknames, MUCRole.moderator);
} }
@ -1161,7 +1175,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantModerator(String nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantModerator(Resourcepart nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nickname, MUCRole.moderator, null); changeRole(nickname, MUCRole.moderator, null);
} }
@ -1177,7 +1191,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeModerator(Collection<String> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeModerator(Collection<Resourcepart> nicknames) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nicknames, MUCRole.participant); changeRole(nicknames, MUCRole.participant);
} }
@ -1193,7 +1207,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeModerator(String nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeModerator(Resourcepart nickname) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeRole(nickname, MUCRole.participant, null); changeRole(nickname, MUCRole.participant, null);
} }
@ -1209,7 +1223,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantOwnership(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantOwnership(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.owner); changeAffiliationByAdmin(jids, MUCAffiliation.owner);
} }
@ -1225,7 +1239,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantOwnership(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantOwnership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.owner, null); changeAffiliationByAdmin(jid, MUCAffiliation.owner, null);
} }
@ -1240,7 +1254,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeOwnership(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeOwnership(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.admin); changeAffiliationByAdmin(jids, MUCAffiliation.admin);
} }
@ -1255,7 +1269,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeOwnership(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeOwnership(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.admin, null); changeAffiliationByAdmin(jid, MUCAffiliation.admin, null);
} }
@ -1270,7 +1284,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantAdmin(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantAdmin(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.admin); changeAffiliationByAdmin(jids, MUCAffiliation.admin);
} }
@ -1286,7 +1300,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void grantAdmin(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void grantAdmin(Jid jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.admin); changeAffiliationByAdmin(jid, MUCAffiliation.admin);
} }
@ -1301,7 +1315,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeAdmin(Collection<String> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeAdmin(Collection<? extends Jid> jids) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jids, MUCAffiliation.admin); changeAffiliationByAdmin(jids, MUCAffiliation.admin);
} }
@ -1317,7 +1331,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void revokeAdmin(String jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException { public void revokeAdmin(JidWithLocalpart jid) throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, MUCAffiliation.member); changeAffiliationByAdmin(jid, MUCAffiliation.member);
} }
@ -1331,7 +1345,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
private void changeAffiliationByAdmin(String jid, MUCAffiliation affiliation) private void changeAffiliationByAdmin(Jid jid, MUCAffiliation affiliation)
throws NoResponseException, XMPPErrorException, throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
changeAffiliationByAdmin(jid, affiliation, null); changeAffiliationByAdmin(jid, affiliation, null);
@ -1348,7 +1362,7 @@ public class MultiUserChat {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
private void changeAffiliationByAdmin(String jid, MUCAffiliation affiliation, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException private void changeAffiliationByAdmin(Jid jid, MUCAffiliation affiliation, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
{ {
MUCAdmin iq = new MUCAdmin(); MUCAdmin iq = new MUCAdmin();
iq.setTo(room); iq.setTo(room);
@ -1360,12 +1374,12 @@ public class MultiUserChat {
connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); connection.createPacketCollectorAndSend(iq).nextResultOrThrow();
} }
private void changeAffiliationByAdmin(Collection<String> jids, MUCAffiliation affiliation) private void changeAffiliationByAdmin(Collection<? extends Jid> jids, MUCAffiliation affiliation)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
MUCAdmin iq = new MUCAdmin(); MUCAdmin iq = new MUCAdmin();
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
for (String jid : jids) { for (Jid jid : jids) {
// Set the new affiliation. // Set the new affiliation.
MUCItem item = new MUCItem(affiliation, jid); MUCItem item = new MUCItem(affiliation, jid);
iq.addItem(item); iq.addItem(item);
@ -1374,7 +1388,7 @@ public class MultiUserChat {
connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); connection.createPacketCollectorAndSend(iq).nextResultOrThrow();
} }
private void changeRole(String nickname, MUCRole role, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private void changeRole(Resourcepart nickname, MUCRole role, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
MUCAdmin iq = new MUCAdmin(); MUCAdmin iq = new MUCAdmin();
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
@ -1385,11 +1399,11 @@ public class MultiUserChat {
connection.createPacketCollectorAndSend(iq).nextResultOrThrow(); connection.createPacketCollectorAndSend(iq).nextResultOrThrow();
} }
private void changeRole(Collection<String> nicknames, MUCRole role) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { private void changeRole(Collection<Resourcepart> nicknames, MUCRole role) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
MUCAdmin iq = new MUCAdmin(); MUCAdmin iq = new MUCAdmin();
iq.setTo(room); iq.setTo(room);
iq.setType(IQ.Type.set); iq.setType(IQ.Type.set);
for (String nickname : nicknames) { for (Resourcepart nickname : nicknames) {
// Set the new role. // Set the new role.
MUCItem item = new MUCItem(role, nickname); MUCItem item = new MUCItem(role, nickname);
iq.addItem(item); iq.addItem(item);
@ -1413,7 +1427,7 @@ public class MultiUserChat {
} }
/** /**
* Returns an Iterator (of Strings) for the list of fully qualified occupants * Returns an List for the list of fully qualified occupants
* in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser". * in the group chat. For example, "conference@chat.jivesoftware.com/SomeUser".
* Typically, a client would only display the nickname of the occupant. To * Typically, a client would only display the nickname of the occupant. To
* get the nickname from the fully qualified name, use the * get the nickname from the fully qualified name, use the
@ -1423,8 +1437,8 @@ public class MultiUserChat {
* *
* @return a List of the occupants in the group chat. * @return a List of the occupants in the group chat.
*/ */
public List<String> getOccupants() { public List<FullJid> getOccupants() {
return Collections.unmodifiableList(new ArrayList<String>(occupantsMap.keySet())); return new ArrayList<>(occupantsMap.keySet());
} }
/** /**
@ -1642,7 +1656,7 @@ public class MultiUserChat {
* created chat. * created chat.
* @return new Chat for sending private messages to a given room occupant. * @return new Chat for sending private messages to a given room occupant.
*/ */
public Chat createPrivateChat(String occupant, ChatMessageListener listener) { public Chat createPrivateChat(FullJid occupant, ChatMessageListener listener) {
return ChatManager.getInstanceFor(connection).createChat(occupant, listener); return ChatManager.getInstanceFor(connection).createChat(occupant, listener);
} }
@ -1884,7 +1898,7 @@ public class MultiUserChat {
MUCRole oldRole, MUCRole oldRole,
MUCRole newRole, MUCRole newRole,
boolean isUserModification, boolean isUserModification,
String from) { FullJid from) {
// Voice was granted to a visitor // Voice was granted to a visitor
if (("visitor".equals(oldRole) || "none".equals(oldRole)) if (("visitor".equals(oldRole) || "none".equals(oldRole))
&& "participant".equals(newRole)) { && "participant".equals(newRole)) {
@ -2010,7 +2024,7 @@ public class MultiUserChat {
MUCAffiliation oldAffiliation, MUCAffiliation oldAffiliation,
MUCAffiliation newAffiliation, MUCAffiliation newAffiliation,
boolean isUserModification, boolean isUserModification,
String from) { FullJid from) {
// First check for revoked affiliation and then for granted affiliations. The idea is to // First check for revoked affiliation and then for granted affiliations. The idea is to
// first fire the "revoke" events and then fire the "grant" events. // first fire the "revoke" events and then fire the "grant" events.
@ -2107,7 +2121,7 @@ public class MultiUserChat {
Set<Status> statusCodes, Set<Status> statusCodes,
boolean isUserModification, boolean isUserModification,
MUCUser mucUser, MUCUser mucUser,
String from) { FullJid from) {
// Check if an occupant was kicked from the room // Check if an occupant was kicked from the room
if (statusCodes.contains(Status.KICKED_307)) { if (statusCodes.contains(Status.KICKED_307)) {
// Check if this occupant was kicked // Check if this occupant was kicked

View file

@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.Manager;
@ -49,10 +50,16 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence; import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.JidWithLocalpart;
public class MultiUserChatManager extends Manager { public class MultiUserChatManager extends Manager {
private final static String DISCO_NODE = MUCInitialPresence.NAMESPACE + "#rooms"; private final static String DISCO_NODE = MUCInitialPresence.NAMESPACE + "#rooms";
private static final Logger LOGGER = Logger.getLogger(MultiUserChatManager.class.getName());
static { static {
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
public void connectionCreated(final XMPPConnection connection) { public void connectionCreated(final XMPPConnection connection) {
@ -71,9 +78,9 @@ public class MultiUserChatManager extends Manager {
XMPPConnection connection = weakRefConnection.get(); XMPPConnection connection = weakRefConnection.get();
if (connection == null) if (connection == null)
return Collections.emptyList(); return Collections.emptyList();
Set<String> joinedRooms = MultiUserChatManager.getInstanceFor(connection).getJoinedRooms(); Set<BareJid> joinedRooms = MultiUserChatManager.getInstanceFor(connection).getJoinedRooms();
List<DiscoverItems.Item> answer = new ArrayList<DiscoverItems.Item>(); List<DiscoverItems.Item> answer = new ArrayList<DiscoverItems.Item>();
for (String room : joinedRooms) { for (BareJid room : joinedRooms) {
answer.add(new DiscoverItems.Item(room)); answer.add(new DiscoverItems.Item(room));
} }
return answer; return answer;
@ -104,14 +111,14 @@ public class MultiUserChatManager extends Manager {
new NotFilter(MessageTypeFilter.ERROR)); new NotFilter(MessageTypeFilter.ERROR));
private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>(); private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>();
private final Set<String> joinedRooms = new HashSet<String>(); private final Set<BareJid> joinedRooms = new HashSet<>();
/** /**
* A Map of MUC JIDs to {@link MultiUserChat} instances. We use weak references for the values in order to allow * A Map of MUC JIDs to {@link MultiUserChat} instances. We use weak references for the values in order to allow
* those instances to get garbage collected. Note that MultiUserChat instances can not get garbage collected while * those instances to get garbage collected. Note that MultiUserChat instances can not get garbage collected while
* the user is joined, because then the MUC will have PacketListeners added to the XMPPConnection. * the user is joined, because then the MUC will have PacketListeners added to the XMPPConnection.
*/ */
private final Map<String, WeakReference<MultiUserChat>> multiUserChats = new HashMap<String, WeakReference<MultiUserChat>>(); private final Map<BareJid, WeakReference<MultiUserChat>> multiUserChats = new HashMap<>();
private MultiUserChatManager(XMPPConnection connection) { private MultiUserChatManager(XMPPConnection connection) {
super(connection); super(connection);
@ -124,8 +131,13 @@ public class MultiUserChatManager extends Manager {
final MUCUser mucUser = MUCUser.from(message); final MUCUser mucUser = MUCUser.from(message);
// Check if the MUCUser extension includes an invitation // Check if the MUCUser extension includes an invitation
if (mucUser.getInvite() != null) { if (mucUser.getInvite() != null) {
BareJid mucJid = message.getFrom().asBareJidIfPossible();
if (mucJid == null) {
LOGGER.warning("Invite to non bare JID: '" + message.toXML() + "'");
return;
}
// Fire event for invitation listeners // Fire event for invitation listeners
final MultiUserChat muc = getMultiUserChat(packet.getFrom()); final MultiUserChat muc = getMultiUserChat(mucJid);
for (final InvitationListener listener : invitationsListeners) { for (final InvitationListener listener : invitationsListeners) {
listener.invitationReceived(connection(), muc, mucUser.getInvite().getFrom(), listener.invitationReceived(connection(), muc, mucUser.getInvite().getFrom(),
mucUser.getInvite().getReason(), mucUser.getPassword(), message); mucUser.getInvite().getReason(), mucUser.getPassword(), message);
@ -138,7 +150,7 @@ public class MultiUserChatManager extends Manager {
/** /**
* Creates a multi user chat. Note: no information is sent to or received from the server until you attempt to * Creates a multi user chat. Note: no information is sent to or received from the server until you attempt to
* {@link MultiUserChat#join(String) join} the chat room. On some server implementations, the room will not be * {@link MultiUserChat#join(org.jxmpp.jid.parts.Resourcepart) join} the chat room. On some server implementations, the room will not be
* created until the first person joins it. * created until the first person joins it.
* <p> * <p>
* Most XMPP servers use a sub-domain for the chat service (eg chat.example.com for the XMPP server example.com). * Most XMPP servers use a sub-domain for the chat service (eg chat.example.com for the XMPP server example.com).
@ -148,7 +160,7 @@ public class MultiUserChatManager extends Manager {
* @param jid the name of the room in the form "roomName@service", where "service" is the hostname at which the * @param jid the name of the room in the form "roomName@service", where "service" is the hostname at which the
* multi-user chat service is running. Make sure to provide a valid JID. * multi-user chat service is running. Make sure to provide a valid JID.
*/ */
public synchronized MultiUserChat getMultiUserChat(String jid) { public synchronized MultiUserChat getMultiUserChat(BareJid jid) {
WeakReference<MultiUserChat> weakRefMultiUserChat = multiUserChats.get(jid); WeakReference<MultiUserChat> weakRefMultiUserChat = multiUserChats.get(jid);
if (weakRefMultiUserChat == null) { if (weakRefMultiUserChat == null) {
return createNewMucAndAddToMap(jid); return createNewMucAndAddToMap(jid);
@ -160,7 +172,7 @@ public class MultiUserChatManager extends Manager {
return multiUserChat; return multiUserChat;
} }
private MultiUserChat createNewMucAndAddToMap(String jid) { private MultiUserChat createNewMucAndAddToMap(BareJid jid) {
MultiUserChat multiUserChat = new MultiUserChat(connection(), jid, this); MultiUserChat multiUserChat = new MultiUserChat(connection(), jid, this);
multiUserChats.put(jid, new WeakReference<MultiUserChat>(multiUserChat)); multiUserChats.put(jid, new WeakReference<MultiUserChat>(multiUserChat));
return multiUserChat; return multiUserChat;
@ -176,7 +188,7 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean isServiceEnabled(String user) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean isServiceEnabled(Jid user) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(user, MUCInitialPresence.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(user, MUCInitialPresence.NAMESPACE);
} }
@ -186,7 +198,7 @@ public class MultiUserChatManager extends Manager {
* *
* @return a List of the rooms where the user has joined using a given connection. * @return a List of the rooms where the user has joined using a given connection.
*/ */
public Set<String> getJoinedRooms() { public Set<BareJid> getJoinedRooms() {
return Collections.unmodifiableSet(joinedRooms); return Collections.unmodifiableSet(joinedRooms);
} }
@ -201,15 +213,20 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<String> getJoinedRooms(String user) throws NoResponseException, XMPPErrorException, public List<BareJid> getJoinedRooms(JidWithLocalpart user) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
// Send the disco packet to the user // Send the disco packet to the user
DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection()).discoverItems(user, DISCO_NODE); DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection()).discoverItems(user, DISCO_NODE);
List<DiscoverItems.Item> items = result.getItems(); List<DiscoverItems.Item> items = result.getItems();
List<String> answer = new ArrayList<String>(items.size()); List<BareJid> answer = new ArrayList<>(items.size());
// Collect the entityID for each returned item // Collect the entityID for each returned item
for (DiscoverItems.Item item : items) { for (DiscoverItems.Item item : items) {
answer.add(item.getEntityID()); BareJid muc = item.getEntityID().asBareJidIfPossible();
if (muc == null) {
LOGGER.warning("Not a bare JID: " + item.getEntityID());
continue;
}
answer.add(muc);
} }
return answer; return answer;
} }
@ -225,7 +242,7 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public RoomInfo getRoomInfo(String room) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public RoomInfo getRoomInfo(BareJid room) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection()).discoverInfo(room); DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection()).discoverInfo(room);
return new RoomInfo(info); return new RoomInfo(info);
} }
@ -239,7 +256,7 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<String> getServiceNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public List<DomainBareJid> getServiceNames() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection()); ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection());
return sdm.findServices(MUCInitialPresence.NAMESPACE, false, false); return sdm.findServices(MUCInitialPresence.NAMESPACE, false, false);
} }
@ -256,7 +273,7 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<HostedRoom> getHostedRooms(String serviceName) throws NoResponseException, XMPPErrorException, public List<HostedRoom> getHostedRooms(DomainBareJid serviceName) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException { NotConnectedException, InterruptedException {
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection()); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection());
DiscoverItems discoverItems = discoManager.discoverItems(serviceName); DiscoverItems discoverItems = discoManager.discoverItems(serviceName);
@ -278,7 +295,7 @@ public class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public void decline(String room, String inviter, String reason) throws NotConnectedException, InterruptedException { public void decline(BareJid room, String inviter, String reason) throws NotConnectedException, InterruptedException {
Message message = new Message(room); Message message = new Message(room);
// Create the MUCUser packet that will include the rejection // Create the MUCUser packet that will include the rejection
@ -311,11 +328,11 @@ public class MultiUserChatManager extends Manager {
invitationsListeners.remove(listener); invitationsListeners.remove(listener);
} }
void addJoinedRoom(String room) { void addJoinedRoom(BareJid room) {
joinedRooms.add(room); joinedRooms.add(room);
} }
void removeJoinedRoom(String room) { void removeJoinedRoom(BareJid room) {
joinedRooms.remove(room); joinedRooms.remove(room);
} }
} }

View file

@ -17,10 +17,14 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import java.util.logging.Logger;
import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.muc.packet.MUCUser;
import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence;
import org.jxmpp.util.XmppStringUtils; import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* Represents the information about an occupant in a given room. The information will always have * Represents the information about an occupant in a given room. The information will always have
@ -29,12 +33,15 @@ import org.jxmpp.util.XmppStringUtils;
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public class Occupant { public class Occupant {
private static final Logger LOGGER = Logger.getLogger(Occupant.class.getName());
// Fields that must have a value // Fields that must have a value
private final MUCAffiliation affiliation; private final MUCAffiliation affiliation;
private final MUCRole role; private final MUCRole role;
// Fields that may have a value // Fields that may have a value
private final String jid; private final Jid jid;
private final String nick; private final Resourcepart nick;
Occupant(MUCItem item) { Occupant(MUCItem item) {
this.jid = item.getJid(); this.jid = item.getJid();
@ -51,7 +58,13 @@ public class Occupant {
this.affiliation = item.getAffiliation(); this.affiliation = item.getAffiliation();
this.role = item.getRole(); this.role = item.getRole();
// Get the nickname from the FROM attribute of the presence // Get the nickname from the FROM attribute of the presence
this.nick = XmppStringUtils.parseResource(presence.getFrom()); FullJid from = presence.getFrom().asFullJidIfPossible();
if (from == null) {
LOGGER.warning("Occupant presence without resource: " + presence.getFrom());
this.nick = null;
} else {
this.nick = from.getResourcepart();
}
} }
/** /**
@ -62,7 +75,7 @@ public class Occupant {
* *
* @return the full JID of the occupant. * @return the full JID of the occupant.
*/ */
public String getJid() { public Jid getJid() {
return jid; return jid;
} }
@ -93,7 +106,7 @@ public class Occupant {
* @return the current nickname of the occupant in the room or null if this information was * @return the current nickname of the occupant in the room or null if this information was
* obtained from a presence. * obtained from a presence.
*/ */
public String getNick() { public Resourcepart getNick() {
return nick; return nick;
} }

View file

@ -17,6 +17,10 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* A listener that is fired anytime a participant's status in a room is changed, such as the * A listener that is fired anytime a participant's status in a room is changed, such as the
* user being kicked, banned, or granted admin permissions. * user being kicked, banned, or granted admin permissions.
@ -33,7 +37,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that has just joined the room * @param participant the participant that has just joined the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void joined(String participant); public abstract void joined(FullJid participant);
/** /**
* Called when a room occupant has left the room on its own. This means that the occupant was * Called when a room occupant has left the room on its own. This means that the occupant was
@ -42,7 +46,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that has left the room on its own. * @param participant the participant that has left the room on its own.
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void left(String participant); public abstract void left(FullJid participant);
/** /**
* Called when a room participant has been kicked from the room. This means that the kicked * Called when a room participant has been kicked from the room. This means that the kicked
@ -53,7 +57,7 @@ public interface ParticipantStatusListener {
* @param actor the moderator that kicked the occupant from the room (e.g. user@host.org). * @param actor the moderator that kicked the occupant from the room (e.g. user@host.org).
* @param reason the reason provided by the actor to kick the occupant from the room. * @param reason the reason provided by the actor to kick the occupant from the room.
*/ */
public abstract void kicked(String participant, String actor, String reason); public abstract void kicked(FullJid participant, Jid actor, String reason);
/** /**
* Called when a moderator grants voice to a visitor. This means that the visitor * Called when a moderator grants voice to a visitor. This means that the visitor
@ -62,7 +66,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was granted voice in the room * @param participant the participant that was granted voice in the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void voiceGranted(String participant); public abstract void voiceGranted(FullJid participant);
/** /**
* Called when a moderator revokes voice from a participant. This means that the participant * Called when a moderator revokes voice from a participant. This means that the participant
@ -72,7 +76,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was revoked voice from the room * @param participant the participant that was revoked voice from the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void voiceRevoked(String participant); public abstract void voiceRevoked(FullJid participant);
/** /**
* Called when an administrator or owner banned a participant from the room. This means that * Called when an administrator or owner banned a participant from the room. This means that
@ -83,7 +87,7 @@ public interface ParticipantStatusListener {
* @param actor the administrator that banned the occupant (e.g. user@host.org). * @param actor the administrator that banned the occupant (e.g. user@host.org).
* @param reason the reason provided by the administrator to ban the occupant. * @param reason the reason provided by the administrator to ban the occupant.
*/ */
public abstract void banned(String participant, String actor, String reason); public abstract void banned(FullJid participant, Jid actor, String reason);
/** /**
* Called when an administrator grants a user membership to the room. This means that the user * Called when an administrator grants a user membership to the room. This means that the user
@ -92,7 +96,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was granted membership in the room * @param participant the participant that was granted membership in the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void membershipGranted(String participant); public abstract void membershipGranted(FullJid participant);
/** /**
* Called when an administrator revokes a user membership to the room. This means that the * Called when an administrator revokes a user membership to the room. This means that the
@ -101,7 +105,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was revoked membership from the room * @param participant the participant that was revoked membership from the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void membershipRevoked(String participant); public abstract void membershipRevoked(FullJid participant);
/** /**
* Called when an administrator grants moderator privileges to a user. This means that the user * Called when an administrator grants moderator privileges to a user. This means that the user
@ -111,7 +115,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was granted moderator privileges in the room * @param participant the participant that was granted moderator privileges in the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void moderatorGranted(String participant); public abstract void moderatorGranted(FullJid participant);
/** /**
* Called when an administrator revokes moderator privileges from a user. This means that the * Called when an administrator revokes moderator privileges from a user. This means that the
@ -121,7 +125,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was revoked moderator privileges in the room * @param participant the participant that was revoked moderator privileges in the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void moderatorRevoked(String participant); public abstract void moderatorRevoked(FullJid participant);
/** /**
* Called when an owner grants a user ownership on the room. This means that the user * Called when an owner grants a user ownership on the room. This means that the user
@ -131,7 +135,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was granted ownership on the room * @param participant the participant that was granted ownership on the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void ownershipGranted(String participant); public abstract void ownershipGranted(FullJid participant);
/** /**
* Called when an owner revokes a user ownership on the room. This means that the user * Called when an owner revokes a user ownership on the room. This means that the user
@ -141,7 +145,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was revoked ownership on the room * @param participant the participant that was revoked ownership on the room
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void ownershipRevoked(String participant); public abstract void ownershipRevoked(FullJid participant);
/** /**
* Called when an owner grants administrator privileges to a user. This means that the user * Called when an owner grants administrator privileges to a user. This means that the user
@ -151,7 +155,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was granted administrator privileges * @param participant the participant that was granted administrator privileges
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void adminGranted(String participant); public abstract void adminGranted(FullJid participant);
/** /**
* Called when an owner revokes administrator privileges from a user. This means that the user * Called when an owner revokes administrator privileges from a user. This means that the user
@ -161,7 +165,7 @@ public interface ParticipantStatusListener {
* @param participant the participant that was revoked administrator privileges * @param participant the participant that was revoked administrator privileges
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void adminRevoked(String participant); public abstract void adminRevoked(FullJid participant);
/** /**
* Called when a participant changed his/her nickname in the room. The new participant's * Called when a participant changed his/her nickname in the room. The new participant's
@ -171,6 +175,6 @@ public interface ParticipantStatusListener {
* (e.g. room@conference.jabber.org/nick). * (e.g. room@conference.jabber.org/nick).
* @param newNickname the new nickname that the participant decided to use. * @param newNickname the new nickname that the participant decided to use.
*/ */
public abstract void nicknameChanged(String participant, String newNickname); public abstract void nicknameChanged(FullJid participant, Resourcepart newNickname);
} }

View file

@ -26,6 +26,8 @@ import java.util.logging.Logger;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
/** /**
* Represents the room information that was discovered using Service Discovery. It's possible to * Represents the room information that was discovered using Service Discovery. It's possible to
@ -39,9 +41,9 @@ public class RoomInfo {
private static final Logger LOGGER = Logger.getLogger(RoomInfo.class.getName()); private static final Logger LOGGER = Logger.getLogger(RoomInfo.class.getName());
/** /**
* JID of the room. The node of the JID is commonly used as the ID of the room or name. * JID of the room. The localpart of the JID is commonly used as the ID of the room or name.
*/ */
private final String room; private final BareJid room;
/** /**
* Description of the room. * Description of the room.
*/ */
@ -128,7 +130,12 @@ public class RoomInfo {
private final Form form; private final Form form;
RoomInfo(DiscoverInfo info) { RoomInfo(DiscoverInfo info) {
this.room = info.getFrom(); final Jid from = info.getFrom();
if (from != null) {
this.room = info.getFrom().asBareJidIfPossible();
} else {
this.room = null;
}
// Get the information based on the discovered features // Get the information based on the discovered features
this.membersOnly = info.containsFeature("muc_membersonly"); this.membersOnly = info.containsFeature("muc_membersonly");
this.moderated = info.containsFeature("muc_moderated"); this.moderated = info.containsFeature("muc_moderated");
@ -233,7 +240,7 @@ public class RoomInfo {
* *
* @return the JID of the room whose information was discovered. * @return the JID of the room whose information was discovered.
*/ */
public String getRoom() { public BareJid getRoom() {
return room; return room;
} }

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jxmpp.jid.FullJid;
/** /**
* A listener that is fired anytime a MUC room changes its subject. * A listener that is fired anytime a MUC room changes its subject.
* *
@ -30,6 +32,6 @@ public interface SubjectUpdatedListener {
* @param subject the new room's subject. * @param subject the new room's subject.
* @param from the user that changed the room's subject (e.g. room@conference.jabber.org/nick). * @param from the user that changed the room's subject (e.g. room@conference.jabber.org/nick).
*/ */
public abstract void subjectUpdated(String subject, String from); public abstract void subjectUpdated(String subject, FullJid from);
} }

View file

@ -17,6 +17,8 @@
package org.jivesoftware.smackx.muc; package org.jivesoftware.smackx.muc;
import org.jxmpp.jid.Jid;
/** /**
* A listener that is fired anytime your participant's status in a room is changed, such as the * A listener that is fired anytime your participant's status in a room is changed, such as the
* user being kicked, banned, or granted admin permissions. * user being kicked, banned, or granted admin permissions.
@ -32,7 +34,7 @@ public interface UserStatusListener {
* @param actor the moderator that kicked your user from the room (e.g. user@host.org). * @param actor the moderator that kicked your user from the room (e.g. user@host.org).
* @param reason the reason provided by the actor to kick you from the room. * @param reason the reason provided by the actor to kick you from the room.
*/ */
public abstract void kicked(String actor, String reason); public abstract void kicked(Jid actor, String reason);
/** /**
* Called when a moderator grants voice to your user. This means that you were a visitor in * Called when a moderator grants voice to your user. This means that you were a visitor in
@ -57,7 +59,7 @@ public interface UserStatusListener {
* @param actor the administrator that banned your user (e.g. user@host.org). * @param actor the administrator that banned your user (e.g. user@host.org).
* @param reason the reason provided by the administrator to banned you. * @param reason the reason provided by the administrator to banned you.
*/ */
public abstract void banned(String actor, String reason); public abstract void banned(Jid actor, String reason);
/** /**
* Called when an administrator grants your user membership to the room. This means that you * Called when an administrator grants your user membership to the room. This means that you

View file

@ -21,6 +21,8 @@ import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.muc.MUCAffiliation; import org.jivesoftware.smackx.muc.MUCAffiliation;
import org.jivesoftware.smackx.muc.MUCRole; import org.jivesoftware.smackx.muc.MUCRole;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
/** /**
* Item child that holds information about roles, affiliation, jids and nicks. * Item child that holds information about roles, affiliation, jids and nicks.
@ -32,10 +34,10 @@ public class MUCItem implements NamedElement {
private final MUCAffiliation affiliation; private final MUCAffiliation affiliation;
private final MUCRole role; private final MUCRole role;
private final String actor; private final Jid actor;
private final String reason; private final String reason;
private final String jid; private final Jid jid;
private final String nick; private final Resourcepart nick;
public MUCItem(MUCAffiliation affiliation) { public MUCItem(MUCAffiliation affiliation) {
this(affiliation, null, null, null, null, null); this(affiliation, null, null, null, null, null);
@ -45,19 +47,19 @@ public class MUCItem implements NamedElement {
this(null, role, null, null, null, null); this(null, role, null, null, null, null);
} }
public MUCItem(MUCRole role, String nick) { public MUCItem(MUCRole role, Resourcepart nick) {
this(null, role, null, null, null, nick); this(null, role, null, null, null, nick);
} }
public MUCItem(MUCAffiliation affiliation, String jid, String reason) { public MUCItem(MUCAffiliation affiliation, Jid jid, String reason) {
this(affiliation, null, null, reason, jid, null); this(affiliation, null, null, reason, jid, null);
} }
public MUCItem(MUCAffiliation affiliation, String jid) { public MUCItem(MUCAffiliation affiliation, Jid jid) {
this(affiliation, null, null, null, jid, null); this(affiliation, null, null, null, jid, null);
} }
public MUCItem(MUCRole role, String nick, String reason) { public MUCItem(MUCRole role, Resourcepart nick, String reason) {
this(null, role, null, reason, null, nick); this(null, role, null, reason, null, nick);
} }
@ -71,8 +73,8 @@ public class MUCItem implements NamedElement {
* @param jid * @param jid
* @param nick * @param nick
*/ */
public MUCItem(MUCAffiliation affiliation, MUCRole role, String actor, public MUCItem(MUCAffiliation affiliation, MUCRole role, Jid actor,
String reason, String jid, String nick) { String reason, Jid jid, Resourcepart nick) {
this.affiliation = affiliation; this.affiliation = affiliation;
this.role = role; this.role = role;
this.actor = actor; this.actor = actor;
@ -86,7 +88,7 @@ public class MUCItem implements NamedElement {
* *
* @return the JID of an occupant in the room that was kicked or banned. * @return the JID of an occupant in the room that was kicked or banned.
*/ */
public String getActor() { public Jid getActor() {
return actor; return actor;
} }
@ -118,7 +120,7 @@ public class MUCItem implements NamedElement {
* *
* @return the room JID by which an occupant is identified within the room. * @return the room JID by which an occupant is identified within the room.
*/ */
public String getJid() { public Jid getJid() {
return jid; return jid;
} }
@ -128,7 +130,7 @@ public class MUCItem implements NamedElement {
* *
* @return the new nickname of an occupant that is changing his/her nickname. * @return the new nickname of an occupant that is changing his/her nickname.
*/ */
public String getNick() { public Resourcepart getNick() {
return nick; return nick;
} }

View file

@ -18,10 +18,13 @@ package org.jivesoftware.smackx.muc.provider;
import java.io.IOException; import java.io.IOException;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.muc.MUCAffiliation; import org.jivesoftware.smackx.muc.MUCAffiliation;
import org.jivesoftware.smackx.muc.MUCRole; import org.jivesoftware.smackx.muc.MUCRole;
import org.jivesoftware.smackx.muc.packet.Destroy; import org.jivesoftware.smackx.muc.packet.Destroy;
import org.jivesoftware.smackx.muc.packet.MUCItem; import org.jivesoftware.smackx.muc.packet.MUCItem;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.parts.Resourcepart;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -29,10 +32,10 @@ public class MUCParserUtils {
public static MUCItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException { public static MUCItem parseItem(XmlPullParser parser) throws XmlPullParserException, IOException {
int initialDepth = parser.getDepth(); int initialDepth = parser.getDepth();
MUCAffiliation affiliation = MUCAffiliation.fromString(parser.getAttributeValue("", "affiliation")); MUCAffiliation affiliation = MUCAffiliation.fromString(parser.getAttributeValue("", "affiliation"));
String nick = parser.getAttributeValue("", "nick"); Resourcepart nick = ParserUtils.getResourcepartAttribute(parser, "nick");
MUCRole role = MUCRole.fromString(parser.getAttributeValue("", "role")); MUCRole role = MUCRole.fromString(parser.getAttributeValue("", "role"));
String jid = parser.getAttributeValue("", "jid"); Jid jid = ParserUtils.getJidAttribute(parser);
String actor = null; Jid actor = null;
String reason = null; String reason = null;
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); int eventType = parser.next();
@ -41,7 +44,7 @@ public class MUCParserUtils {
String name = parser.getName(); String name = parser.getName();
switch (name) { switch (name) {
case "actor": case "actor":
actor = parser.getAttributeValue("", "jid"); actor = ParserUtils.getJidAttribute(parser);
break; break;
case "reason": case "reason":
reason = parser.nextText(); reason = parser.nextText();

View file

@ -18,6 +18,7 @@
package org.jivesoftware.smackx.offline; package org.jivesoftware.smackx.offline;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jxmpp.jid.Jid;
/** /**
* The OfflineMessageHeader holds header information of an offline message. The header * The OfflineMessageHeader holds header information of an offline message. The header
@ -32,7 +33,7 @@ public class OfflineMessageHeader {
/** /**
* Bare JID of the user that was offline when the message was sent. * Bare JID of the user that was offline when the message was sent.
*/ */
private String user; private Jid user;
/** /**
* Full JID of the user that sent the message. * Full JID of the user that sent the message.
*/ */
@ -56,7 +57,7 @@ public class OfflineMessageHeader {
* *
* @return the bare JID of the user that was offline when the message was sent. * @return the bare JID of the user that was offline when the message was sent.
*/ */
public String getUser() { public Jid getUser() {
return user; return user;
} }

View file

@ -18,6 +18,7 @@
package org.jivesoftware.smackx.pep; package org.jivesoftware.smackx.pep;
import org.jivesoftware.smackx.pep.packet.PEPEvent; import org.jivesoftware.smackx.pep.packet.PEPEvent;
import org.jxmpp.jid.Jid;
/** /**
@ -34,6 +35,6 @@ public interface PEPListener {
* @param from the user that sent the entries. * @param from the user that sent the entries.
* @param event the event contained in the message. * @param event the event contained in the message.
*/ */
public void eventReceived(String from, PEPEvent event); public void eventReceived(Jid from, PEPEvent event);
} }

View file

@ -31,6 +31,7 @@ import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smackx.pep.packet.PEPEvent; import org.jivesoftware.smackx.pep.packet.PEPEvent;
import org.jivesoftware.smackx.pep.packet.PEPItem; import org.jivesoftware.smackx.pep.packet.PEPItem;
import org.jivesoftware.smackx.pep.packet.PEPPubSub; import org.jivesoftware.smackx.pep.packet.PEPPubSub;
import org.jxmpp.jid.Jid;
/** /**
* *
@ -122,7 +123,7 @@ public class PEPManager {
/** /**
* Fires roster exchange listeners. * Fires roster exchange listeners.
*/ */
private void firePEPListeners(String from, PEPEvent event) { private void firePEPListeners(Jid from, PEPEvent event) {
PEPListener[] listeners = null; PEPListener[] listeners = null;
synchronized (pepListeners) { synchronized (pepListeners) {
listeners = new PEPListener[pepListeners.size()]; listeners = new PEPListener[pepListeners.size()];

View file

@ -45,6 +45,7 @@ import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.util.SmackExecutorThreadFactory; import org.jivesoftware.smack.util.SmackExecutorThreadFactory;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.ping.packet.Ping; import org.jivesoftware.smackx.ping.packet.Ping;
import org.jxmpp.jid.Jid;
/** /**
* Implements the XMPP Ping as defined by XEP-0199. The XMPP Ping protocol allows one entity to * Implements the XMPP Ping as defined by XEP-0199. The XMPP Ping protocol allows one entity to
@ -147,7 +148,7 @@ public class PingManager extends Manager {
* to this, is a server ping, which will always return true if the server is reachable, * to this, is a server ping, which will always return true if the server is reachable,
* event if there is an error on the ping itself (i.e. ping not supported). * event if there is an error on the ping itself (i.e. ping not supported).
* <p> * <p>
* Use {@link #isPingSupported(String)} to determine if XMPP Ping is supported * Use {@link #isPingSupported(Jid)} to determine if XMPP Ping is supported
* by the entity. * by the entity.
* *
* @param jid The id of the entity the ping is being sent to * @param jid The id of the entity the ping is being sent to
@ -157,7 +158,7 @@ public class PingManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean ping(String jid, long pingTimeout) throws NotConnectedException, NoResponseException, InterruptedException { public boolean ping(Jid jid, long pingTimeout) throws NotConnectedException, NoResponseException, InterruptedException {
final XMPPConnection connection = connection(); final XMPPConnection connection = connection();
// Packet collector for IQs needs an connection that was at least authenticated once, // Packet collector for IQs needs an connection that was at least authenticated once,
// otherwise the client JID will be null causing an NPE // otherwise the client JID will be null causing an NPE
@ -175,7 +176,7 @@ public class PingManager extends Manager {
} }
/** /**
* Same as calling {@link #ping(String, long)} with the defaultpacket reply * Same as calling {@link #ping(Jid, long)} with the defaultpacket reply
* timeout. * timeout.
* *
* @param jid The id of the entity the ping is being sent to * @param jid The id of the entity the ping is being sent to
@ -184,7 +185,7 @@ public class PingManager extends Manager {
* @throws NoResponseException if there was no response from the jid. * @throws NoResponseException if there was no response from the jid.
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean ping(String jid) throws NotConnectedException, NoResponseException, InterruptedException { public boolean ping(Jid jid) throws NotConnectedException, NoResponseException, InterruptedException {
return ping(jid, connection().getPacketReplyTimeout()); return ping(jid, connection().getPacketReplyTimeout());
} }
@ -198,7 +199,7 @@ public class PingManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean isPingSupported(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean isPingSupported(Jid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, Ping.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, Ping.NAMESPACE);
} }
@ -206,8 +207,8 @@ public class PingManager extends Manager {
* Pings the server. This method will return true if the server is reachable. It * Pings the server. This method will return true if the server is reachable. It
* is the equivalent of calling <code>ping</code> with the XMPP domain. * is the equivalent of calling <code>ping</code> with the XMPP domain.
* <p> * <p>
* Unlike the {@link #ping(String)} case, this method will return true even if * Unlike the {@link #ping(Jid)} case, this method will return true even if
* {@link #isPingSupported(String)} is false. * {@link #isPingSupported(Jid)} is false.
* *
* @return true if a reply was received from the server, false otherwise. * @return true if a reply was received from the server, false otherwise.
* @throws NotConnectedException * @throws NotConnectedException
@ -221,8 +222,8 @@ public class PingManager extends Manager {
* Pings the server. This method will return true if the server is reachable. It * Pings the server. This method will return true if the server is reachable. It
* is the equivalent of calling <code>ping</code> with the XMPP domain. * is the equivalent of calling <code>ping</code> with the XMPP domain.
* <p> * <p>
* Unlike the {@link #ping(String)} case, this method will return true even if * Unlike the {@link #ping(Jid)} case, this method will return true even if
* {@link #isPingSupported(String)} is false. * {@link #isPingSupported(Jid)} is false.
* *
* @param notifyListeners Notify the PingFailedListener in case of error if true * @param notifyListeners Notify the PingFailedListener in case of error if true
* @return true if the user's server could be pinged. * @return true if the user's server could be pinged.
@ -237,8 +238,8 @@ public class PingManager extends Manager {
* Pings the server. This method will return true if the server is reachable. It * Pings the server. This method will return true if the server is reachable. It
* is the equivalent of calling <code>ping</code> with the XMPP domain. * is the equivalent of calling <code>ping</code> with the XMPP domain.
* <p> * <p>
* Unlike the {@link #ping(String)} case, this method will return true even if * Unlike the {@link #ping(Jid)} case, this method will return true even if
* {@link #isPingSupported(String)} is false. * {@link #isPingSupported(Jid)} is false.
* *
* @param notifyListeners Notify the PingFailedListener in case of error if true * @param notifyListeners Notify the PingFailedListener in case of error if true
* @param pingTimeout The time to wait for a reply in milliseconds * @param pingTimeout The time to wait for a reply in milliseconds

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2012 Florian Schmaus * Copyright 2012-2015 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.jivesoftware.smackx.ping.packet;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.packet.SimpleIQ;
import org.jxmpp.jid.Jid;
public class Ping extends SimpleIQ { public class Ping extends SimpleIQ {
@ -28,7 +29,7 @@ public class Ping extends SimpleIQ {
super(ELEMENT, NAMESPACE); super(ELEMENT, NAMESPACE);
} }
public Ping(String to) { public Ping(Jid to) {
this(); this();
setTo(to); setTo(to);
setType(IQ.Type.get); setType(IQ.Type.get);

View file

@ -106,6 +106,24 @@ public class PrivacyItem {
this.order = order; this.order = order;
} }
/**
* Creates a new privacy item.
*
* If the type is "jid", then the 'value' attribute MUST contain a valid Jabber ID.
* If the type is "group", then the 'value' attribute SHOULD contain the name of a group
* in the user's roster.
* If the type is "subscription", then the 'value' attribute MUST be one of "both", "to",
* "from", or "none".
*
* @param type the type.
* @param value the value of the privacy item
* @param allow true if this is an allow item
* @param order the order of this privacy item
*/
public PrivacyItem(Type type, CharSequence value, boolean allow, long order) {
this(type, value != null ? value.toString() : null, allow, order);
}
/** /**
* Returns the action associated with the item, it MUST be filled and will allow or deny * Returns the action associated with the item, it MUST be filled and will allow or deny
* the communication. * the communication.

View file

@ -43,12 +43,13 @@ import org.jivesoftware.smackx.pubsub.util.NodeUtils;
import org.jivesoftware.smackx.shim.packet.Header; import org.jivesoftware.smackx.shim.packet.Header;
import org.jivesoftware.smackx.shim.packet.HeadersExtension; import org.jivesoftware.smackx.shim.packet.HeadersExtension;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.Jid;
abstract public class Node abstract public class Node
{ {
protected XMPPConnection con; protected XMPPConnection con;
protected String id; protected String id;
protected String to; protected Jid to;
protected ConcurrentHashMap<ItemEventListener<Item>, PacketListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, PacketListener>(); protected ConcurrentHashMap<ItemEventListener<Item>, PacketListener> itemEventToListenerMap = new ConcurrentHashMap<ItemEventListener<Item>, PacketListener>();
protected ConcurrentHashMap<ItemDeleteListener, PacketListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, PacketListener>(); protected ConcurrentHashMap<ItemDeleteListener, PacketListener> itemDeleteToListenerMap = new ConcurrentHashMap<ItemDeleteListener, PacketListener>();
@ -73,7 +74,7 @@ abstract public class Node
* *
* For example, OpenFire requires the server to be prefixed by <b>pubsub</b> * For example, OpenFire requires the server to be prefixed by <b>pubsub</b>
*/ */
void setTo(String toAddress) void setTo(Jid toAddress)
{ {
to = toAddress; to = toAddress;
} }

View file

@ -38,6 +38,10 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
import org.jivesoftware.smackx.pubsub.util.NodeUtils; import org.jivesoftware.smackx.pubsub.util.NodeUtils;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
/** /**
* This is the starting point for access to the pubsub service. It * This is the starting point for access to the pubsub service. It
@ -51,7 +55,7 @@ import org.jivesoftware.smackx.xdata.FormField;
final public class PubSubManager final public class PubSubManager
{ {
private XMPPConnection con; private XMPPConnection con;
private String to; private DomainBareJid to;
private Map<String, Node> nodeMap = new ConcurrentHashMap<String, Node>(); private Map<String, Node> nodeMap = new ConcurrentHashMap<String, Node>();
/** /**
@ -59,11 +63,12 @@ final public class PubSubManager
* name to <i>pubsub</i> * name to <i>pubsub</i>
* *
* @param connection The XMPP connection * @param connection The XMPP connection
* @throws XmppStringprepException
*/ */
public PubSubManager(XMPPConnection connection) public PubSubManager(XMPPConnection connection) throws XmppStringprepException
{ {
con = connection; con = connection;
to = "pubsub." + connection.getServiceName(); to = JidCreate.domainBareFrom("pubsub." + connection.getServiceName());
} }
/** /**
@ -73,7 +78,7 @@ final public class PubSubManager
* @param connection The XMPP connection * @param connection The XMPP connection
* @param toAddress The pubsub specific to address (required for some servers) * @param toAddress The pubsub specific to address (required for some servers)
*/ */
public PubSubManager(XMPPConnection connection, String toAddress) public PubSubManager(XMPPConnection connection, DomainBareJid toAddress)
{ {
con = connection; con = connection;
to = toAddress; to = toAddress;
@ -314,7 +319,7 @@ final public class PubSubManager
return sendPubsubPacket(con, to, type, Collections.singletonList(ext), ns); return sendPubsubPacket(con, to, type, Collections.singletonList(ext), ns);
} }
static PubSub sendPubsubPacket(XMPPConnection con, String to, Type type, List<PacketExtension> extList, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException static PubSub sendPubsubPacket(XMPPConnection con, Jid to, Type type, List<PacketExtension> extList, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException
{ {
PubSub pubSub = new PubSub(to, type, ns); PubSub pubSub = new PubSub(to, type, ns);
for (PacketExtension pe : extList) { for (PacketExtension pe : extList) {

View file

@ -19,6 +19,7 @@ package org.jivesoftware.smackx.pubsub.packet;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.PacketExtension;
import org.jivesoftware.smackx.pubsub.PubSubElementType; import org.jivesoftware.smackx.pubsub.PubSubElementType;
import org.jxmpp.jid.Jid;
/** /**
* The standard PubSub extension of an {@link IQ} packet. This is the topmost * The standard PubSub extension of an {@link IQ} packet. This is the topmost
@ -40,7 +41,7 @@ public class PubSub extends IQ
super(ELEMENT, ns.getXmlns()); super(ELEMENT, ns.getXmlns());
} }
public PubSub(String to, Type type, PubSubNamespace ns) { public PubSub(Jid to, Type type, PubSubNamespace ns) {
super(ELEMENT, (ns == null ? PubSubNamespace.BASIC : ns).getXmlns()); super(ELEMENT, (ns == null ? PubSubNamespace.BASIC : ns).getXmlns());
setTo(to); setTo(to);
setType(type); setType(type);
@ -86,7 +87,7 @@ public class PubSub extends IQ
return xml; return xml;
} }
public static PubSub createPubsubPacket(String to, Type type, PacketExtension extension, PubSubNamespace ns) { public static PubSub createPubsubPacket(Jid to, Type type, PacketExtension extension, PubSubNamespace ns) {
PubSub pubSub = new PubSub(to, type, ns); PubSub pubSub = new PubSub(to, type, ns);
pubSub.addExtension(extension); pubSub.addExtension(extension);
return pubSub; return pubSub;

View file

@ -38,6 +38,7 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jxmpp.jid.Jid;
/** /**
* Manager for XEP-0184: Message Delivery Receipts. This class implements * Manager for XEP-0184: Message Delivery Receipts. This class implements
@ -142,7 +143,7 @@ public class DeliveryReceiptManager extends Manager {
connection.addAsyncPacketListener(new PacketListener() { connection.addAsyncPacketListener(new PacketListener() {
@Override @Override
public void processPacket(Stanza packet) throws NotConnectedException, InterruptedException { public void processPacket(Stanza packet) throws NotConnectedException, InterruptedException {
final String from = packet.getFrom(); final Jid from = packet.getFrom();
final XMPPConnection connection = connection(); final XMPPConnection connection = connection();
switch (autoReceiptMode) { switch (autoReceiptMode) {
case disabled: case disabled:
@ -190,7 +191,7 @@ public class DeliveryReceiptManager extends Manager {
* @throws XMPPException * @throws XMPPException
* @throws InterruptedException * @throws InterruptedException
*/ */
public boolean isSupported(String jid) throws SmackException, XMPPException, InterruptedException { public boolean isSupported(Jid jid) throws SmackException, XMPPException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid,
DeliveryReceipt.NAMESPACE); DeliveryReceipt.NAMESPACE);
} }

View file

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.receipts; package org.jivesoftware.smackx.receipts;
import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Stanza;
import org.jxmpp.jid.Jid;
/** /**
* Interface for received receipt notifications. * Interface for received receipt notifications.
@ -36,5 +37,5 @@ public interface ReceiptReceivedListener {
* @param receiptId the message ID of the packet which has been received and this receipt is for * @param receiptId the message ID of the packet which has been received and this receipt is for
* @param receipt the receipt * @param receipt the receipt
*/ */
void onReceiptReceived(String fromJid, String toJid, String receiptId, Stanza receipt); void onReceiptReceived(Jid fromJid, Jid toJid, String receiptId, Stanza receipt);
} }

View file

@ -30,6 +30,7 @@ import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.DomainBareJid;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@ -66,7 +67,7 @@ public class UserSearch extends SimpleIQ {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public Form getSearchForm(XMPPConnection con, String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public Form getSearchForm(XMPPConnection con, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
UserSearch search = new UserSearch(); UserSearch search = new UserSearch();
search.setType(IQ.Type.get); search.setType(IQ.Type.get);
search.setTo(searchService); search.setTo(searchService);
@ -87,7 +88,7 @@ public class UserSearch extends SimpleIQ {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public ReportedData sendSearchForm(XMPPConnection con, Form searchForm, String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public ReportedData sendSearchForm(XMPPConnection con, Form searchForm, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
UserSearch search = new UserSearch(); UserSearch search = new UserSearch();
search.setType(IQ.Type.set); search.setType(IQ.Type.set);
search.setTo(searchService); search.setTo(searchService);
@ -109,7 +110,7 @@ public class UserSearch extends SimpleIQ {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public ReportedData sendSimpleSearchForm(XMPPConnection con, Form searchForm, String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public ReportedData sendSimpleSearchForm(XMPPConnection con, Form searchForm, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
SimpleUserSearch search = new SimpleUserSearch(); SimpleUserSearch search = new SimpleUserSearch();
search.setForm(searchForm); search.setForm(searchForm);
search.setType(IQ.Type.set); search.setType(IQ.Type.set);

View file

@ -22,6 +22,7 @@ import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.Form;
import org.jxmpp.jid.DomainBareJid;
import java.util.List; import java.util.List;
@ -68,7 +69,7 @@ public class UserSearchManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public Form getSearchForm(String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public Form getSearchForm(DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return userSearch.getSearchForm(con, searchService); return userSearch.getSearchForm(con, searchService);
} }
@ -84,7 +85,7 @@ public class UserSearchManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public ReportedData getSearchResults(Form searchForm, String searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public ReportedData getSearchResults(Form searchForm, DomainBareJid searchService) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return userSearch.sendSearchForm(con, searchForm, searchService); return userSearch.sendSearchForm(con, searchForm, searchService);
} }
@ -98,7 +99,7 @@ public class UserSearchManager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
*/ */
public List<String> getSearchServices() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public List<DomainBareJid> getSearchServices() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con);
return discoManager.findServices(UserSearch.NAMESPACE, false, false); return discoManager.findServices(UserSearch.NAMESPACE, false, false);
} }

View file

@ -34,6 +34,7 @@ import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.packet.XMPPError.Condition; import org.jivesoftware.smack.packet.XMPPError.Condition;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.time.packet.Time; import org.jivesoftware.smackx.time.packet.Time;
import org.jxmpp.jid.Jid;
public class EntityTimeManager extends Manager { public class EntityTimeManager extends Manager {
@ -99,11 +100,11 @@ public class EntityTimeManager extends Manager {
enabled = false; enabled = false;
} }
public boolean isTimeSupported(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public boolean isTimeSupported(Jid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, Time.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, Time.NAMESPACE);
} }
public Time getTime(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { public Time getTime(Jid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
if (!isTimeSupported(jid)) if (!isTimeSupported(jid))
return null; return null;

Some files were not shown because too many files have changed in this diff Show more