mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-09-10 17:49:38 +02:00
Apply builder pattern to ConnectionConfiguration
Introducing a clean split between the constant connection configuration parameters, which are now all in ConnectionConfiguration and the dynamic connection state (e.g. hostAddresses) which are now in AbstractXMPPConnection. Also removed all arguments of login() since the username, password, resource and callback handler need now to be configured via ConnectionConfiguration. Also remove documentation/extensions/messageevents.md, as it's already in documentation/legacy
This commit is contained in:
parent
69f387b344
commit
c81cd34561
24 changed files with 760 additions and 708 deletions
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack;
|
|||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
@ -39,7 +40,10 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.ConnectionConfigurationBuilder;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
||||
import org.jivesoftware.smack.SmackException.AlreadyConnectedException;
|
||||
import org.jivesoftware.smack.SmackException.AlreadyLoggedInException;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.SmackException.ConnectionException;
|
||||
|
@ -66,7 +70,9 @@ import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
|||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smack.rosterstore.RosterStore;
|
||||
import org.jivesoftware.smack.util.Async;
|
||||
import org.jivesoftware.smack.util.DNSUtil;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||
import org.jxmpp.util.XmppStringUtils;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
@ -255,8 +261,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
*/
|
||||
protected boolean wasAuthenticated = false;
|
||||
|
||||
private boolean anonymous = false;
|
||||
|
||||
/**
|
||||
* Create a new XMPPConnection to a XMPP server.
|
||||
*
|
||||
|
@ -272,6 +276,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
|
||||
@Override
|
||||
public String getServiceName() {
|
||||
if (serviceName != null) {
|
||||
return serviceName;
|
||||
}
|
||||
return config.getServiceName();
|
||||
}
|
||||
|
||||
|
@ -312,6 +319,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
* @throws ConnectionException with detailed information about the failed connection.
|
||||
*/
|
||||
public void connect() throws SmackException, IOException, XMPPException {
|
||||
throwAlreadyConnectedExceptionIfAppropriate();
|
||||
saslAuthentication.init();
|
||||
saslFeatureReceived.init();
|
||||
lastFeaturesReceived.init();
|
||||
|
@ -340,64 +348,31 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
* Before logging in (i.e. authenticate) to the server the connection must be connected.
|
||||
*
|
||||
* It is possible to log in without sending an initial available presence by using
|
||||
* {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is
|
||||
* {@link ConnectionConfigurationBuilder#setSendPresence(boolean)}. If this connection is
|
||||
* not interested in loading its roster upon login then use
|
||||
* {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}.
|
||||
* {@link ConnectionConfigurationBuilder#setRosterLoadedAtLogin(boolean)}.
|
||||
* Finally, if you want to not pass a password and instead use a more advanced mechanism
|
||||
* while using SASL then you may be interested in using
|
||||
* {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
|
||||
* {@link ConnectionConfigurationBuilder#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
|
||||
* For more advanced login settings see {@link ConnectionConfiguration}.
|
||||
*
|
||||
* @param username the username.
|
||||
* @param password the password or <tt>null</tt> if using a CallbackHandler.
|
||||
* @throws XMPPException if an error occurs on the XMPP protocol level.
|
||||
* @throws SmackException if an error occurs somehwere else besides XMPP protocol level.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void login(String username, String password) throws XMPPException, SmackException, IOException {
|
||||
login(username, password, "Smack");
|
||||
public void login() throws XMPPException, SmackException, IOException {
|
||||
throwNotConnectedExceptionIfAppropriate();
|
||||
throwAlreadyLoggedInExceptionIfAppropriate();
|
||||
if (isAnonymous()) {
|
||||
loginAnonymously();
|
||||
} else {
|
||||
loginNonAnonymously();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in to the server using the strongest authentication mode supported by
|
||||
* the server, then sets presence to available. If the server supports SASL authentication
|
||||
* then the user will be authenticated using SASL if not Non-SASL authentication will
|
||||
* be tried. If more than five seconds (default timeout) elapses in each step of the
|
||||
* authentication process without a response from the server, or if an error occurs, a
|
||||
* XMPPException will be thrown.<p>
|
||||
*
|
||||
* Before logging in (i.e. authenticate) to the server the connection must be connected.
|
||||
*
|
||||
* It is possible to log in without sending an initial available presence by using
|
||||
* {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is
|
||||
* not interested in loading its roster upon login then use
|
||||
* {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}.
|
||||
* Finally, if you want to not pass a password and instead use a more advanced mechanism
|
||||
* while using SASL then you may be interested in using
|
||||
* {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}.
|
||||
* For more advanced login settings see {@link ConnectionConfiguration}.
|
||||
*
|
||||
* @param username the username.
|
||||
* @param password the password or <tt>null</tt> if using a CallbackHandler.
|
||||
* @param resource the resource.
|
||||
* @throws XMPPException if an error occurs on the XMPP protocol level.
|
||||
* @throws SmackException if an error occurs somehwere else besides XMPP protocol level.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void login(String username, String password, String resource) throws XMPPException, SmackException, IOException;
|
||||
|
||||
/**
|
||||
* Logs in to the server anonymously. Very few servers are configured to support anonymous
|
||||
* authentication, so it's fairly likely logging in anonymously will fail. If anonymous login
|
||||
* does succeed, your XMPP address will likely be in the form "123ABC@server/789XYZ" or
|
||||
* "server/123ABC" (where "123ABC" and "789XYZ" is a random value generated by the server).
|
||||
*
|
||||
* @throws XMPPException if an error occurs on the XMPP protocol level.
|
||||
* @throws SmackException if an error occurs somehwere else besides XMPP protocol level.
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void loginAnonymously() throws XMPPException, SmackException, IOException;
|
||||
protected abstract void loginNonAnonymously() throws XMPPException, SmackException, IOException;
|
||||
|
||||
protected abstract void loginAnonymously() throws XMPPException, SmackException, IOException;
|
||||
|
||||
@Override
|
||||
public final boolean isConnected() {
|
||||
|
@ -437,7 +412,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
PacketCollector packetCollector = createPacketCollectorAndSend(new PacketIDFilter(bindResource), bindResource);
|
||||
Bind response = packetCollector.nextResultOrThrow();
|
||||
user = response.getJid();
|
||||
setServiceName(XmppStringUtils.parseDomain(user));
|
||||
serviceName = XmppStringUtils.parseDomain(user);
|
||||
|
||||
if (hasFeature(Session.ELEMENT, Session.NAMESPACE) && !getConfiguration().isLegacySessionDisabled()) {
|
||||
Session session = new Session();
|
||||
|
@ -446,10 +421,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
protected void afterSuccessfulLogin(final boolean anonymous, final boolean resumed) throws NotConnectedException {
|
||||
protected void afterSuccessfulLogin(final boolean resumed) throws NotConnectedException {
|
||||
// Indicate that we're now authenticated.
|
||||
this.authenticated = true;
|
||||
this.anonymous = anonymous;
|
||||
|
||||
// If debugging is enabled, change the the debug window title to include the
|
||||
// name we are now logged-in as.
|
||||
|
@ -476,33 +450,53 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
|
||||
@Override
|
||||
public boolean isAnonymous() {
|
||||
return anonymous;
|
||||
return config.isAnonymous();
|
||||
}
|
||||
|
||||
protected void setServiceName(String serviceName) {
|
||||
config.setServiceName(serviceName);
|
||||
}
|
||||
private String serviceName;
|
||||
|
||||
protected void setLoginInfo(String username, String password, String resource) {
|
||||
config.setLoginInfo(username, password, resource);
|
||||
}
|
||||
protected List<HostAddress> hostAddresses;
|
||||
|
||||
protected void maybeResolveDns() throws Exception {
|
||||
config.maybeResolveDns();
|
||||
protected void populateHostAddresses() throws Exception {
|
||||
// N.B.: Important to use config.serviceName and not AbstractXMPPConnection.serviceName
|
||||
if (config.host != null) {
|
||||
hostAddresses = new ArrayList<HostAddress>(1);
|
||||
HostAddress hostAddress;
|
||||
hostAddress = new HostAddress(config.host, config.port);
|
||||
hostAddresses.add(hostAddress);
|
||||
} else {
|
||||
hostAddresses = DNSUtil.resolveXMPPDomain(config.serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
protected Lock getConnectionLock() {
|
||||
return connectionLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Packet packet) throws NotConnectedException {
|
||||
protected void throwNotConnectedExceptionIfAppropriate() throws NotConnectedException {
|
||||
if (!isConnected()) {
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected void throwAlreadyConnectedExceptionIfAppropriate() throws AlreadyConnectedException {
|
||||
if (isConnected()) {
|
||||
throw new AlreadyConnectedException();
|
||||
}
|
||||
}
|
||||
|
||||
protected void throwAlreadyLoggedInExceptionIfAppropriate() throws AlreadyLoggedInException {
|
||||
if (isAuthenticated()) {
|
||||
throw new AlreadyLoggedInException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacket(Packet packet) throws NotConnectedException {
|
||||
if (packet == null) {
|
||||
throw new IllegalArgumentException("Packet must not be null");
|
||||
}
|
||||
throwNotConnectedExceptionIfAppropriate();
|
||||
switch (fromMode) {
|
||||
case OMITTED:
|
||||
packet.setFrom(null);
|
||||
|
@ -897,9 +891,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
* Sets whether the connection has already logged in the server. This method assures that the
|
||||
* {@link #wasAuthenticated} flag is never reset once it has ever been set.
|
||||
*
|
||||
* @param authenticated true if the connection has already been authenticated.
|
||||
*/
|
||||
protected void setWasAuthenticated(boolean authenticated) {
|
||||
protected void setWasAuthenticated() {
|
||||
// Never reset the flag if the connection has ever been authenticated
|
||||
if (!wasAuthenticated) {
|
||||
wasAuthenticated = authenticated;
|
||||
|
@ -1229,4 +1222,5 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
protected void reportStanzaReceived() {
|
||||
this.lastStanzaReceived = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,33 +17,23 @@
|
|||
|
||||
package org.jivesoftware.smack;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.jivesoftware.smack.packet.Session;
|
||||
import org.jivesoftware.smack.proxy.ProxyInfo;
|
||||
import org.jivesoftware.smack.rosterstore.RosterStore;
|
||||
import org.jivesoftware.smack.util.DNSUtil;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||
import org.jxmpp.util.XmppStringUtils;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Configuration to use while establishing the connection to the server. It is possible to
|
||||
* configure the path to the trustore file that keeps the trusted CA root certificates and
|
||||
* enable or disable all or some of the checkings done while verifying server certificates.<p>
|
||||
*
|
||||
* It is also possible to configure if TLS, SASL, and compression are used or not.
|
||||
* Configuration to use while establishing the connection to the server.
|
||||
*
|
||||
* @author Gaston Dombiak
|
||||
*/
|
||||
public class ConnectionConfiguration implements Cloneable {
|
||||
public abstract class ConnectionConfiguration {
|
||||
|
||||
static {
|
||||
// Ensure that Smack is initialized when ConnectionConfiguration is used, or otherwise e.g.
|
||||
|
@ -56,168 +46,104 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
* of the server. However, there are some servers like google where host would be
|
||||
* talk.google.com and the serviceName would be gmail.com.
|
||||
*/
|
||||
private String serviceName;
|
||||
protected final String serviceName;
|
||||
protected final String host;
|
||||
protected final int port;
|
||||
|
||||
protected List<HostAddress> hostAddresses;
|
||||
|
||||
private String keystorePath;
|
||||
private String keystoreType;
|
||||
private String pkcs11Library;
|
||||
private SSLContext customSSLContext;
|
||||
|
||||
private boolean compressionEnabled = false;
|
||||
private final String keystorePath;
|
||||
private final String keystoreType;
|
||||
private final String pkcs11Library;
|
||||
private final SSLContext customSSLContext;
|
||||
|
||||
/**
|
||||
* Used to get information from the user
|
||||
*/
|
||||
private CallbackHandler callbackHandler;
|
||||
private final CallbackHandler callbackHandler;
|
||||
|
||||
private boolean debuggerEnabled = SmackConfiguration.DEBUG_ENABLED;
|
||||
private final boolean debuggerEnabled;
|
||||
|
||||
// Holds the socket factory that is used to generate the socket in the connection
|
||||
private SocketFactory socketFactory;
|
||||
|
||||
// Holds the authentication information for future reconnections
|
||||
private String username;
|
||||
private String password;
|
||||
private String resource;
|
||||
private boolean sendPresence = true;
|
||||
private boolean rosterLoadedAtLogin = true;
|
||||
private boolean legacySessionDisabled = false;
|
||||
private boolean useDnsSrvRr = true;
|
||||
private SecurityMode securityMode = SecurityMode.enabled;
|
||||
private final SocketFactory socketFactory;
|
||||
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final String resource;
|
||||
private final boolean sendPresence;
|
||||
private final boolean rosterLoadedAtLogin;
|
||||
private final boolean legacySessionDisabled;
|
||||
private final SecurityMode securityMode;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String[] enabledSSLProtocols;
|
||||
private final String[] enabledSSLProtocols;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private String[] enabledSSLCiphers;
|
||||
private final String[] enabledSSLCiphers;
|
||||
|
||||
private HostnameVerifier hostnameVerifier;
|
||||
private final HostnameVerifier hostnameVerifier;
|
||||
|
||||
/**
|
||||
* Permanent store for the Roster, needed for roster versioning
|
||||
*/
|
||||
private RosterStore rosterStore;
|
||||
private final RosterStore rosterStore;
|
||||
|
||||
// Holds the proxy information (such as proxyhost, proxyport, username, password etc)
|
||||
protected ProxyInfo proxy;
|
||||
protected final ProxyInfo proxy;
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration for the specified service name.
|
||||
* A DNS SRV lookup will be performed to find out the actual host address
|
||||
* and port to use for the connection.
|
||||
*
|
||||
* @param serviceName the name of the service provided by an XMPP server.
|
||||
*/
|
||||
public ConnectionConfiguration(String serviceName) {
|
||||
init(serviceName, ProxyInfo.forDefaultProxy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration for the specified service name
|
||||
* with specified proxy.
|
||||
* A DNS SRV lookup will be performed to find out the actual host address
|
||||
* and port to use for the connection.
|
||||
*
|
||||
* @param serviceName the name of the service provided by an XMPP server.
|
||||
* @param proxy the proxy through which XMPP is to be connected
|
||||
*/
|
||||
public ConnectionConfiguration(String serviceName,ProxyInfo proxy) {
|
||||
init(serviceName, proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration using the specified host, port and
|
||||
* service name. This is useful for manually overriding the DNS SRV lookup
|
||||
* process that's used with the {@link #ConnectionConfiguration(String)}
|
||||
* constructor. For example, say that an XMPP server is running at localhost
|
||||
* in an internal network on port 5222 but is configured to think that it's
|
||||
* "example.com" for testing purposes. This constructor is necessary to connect
|
||||
* to the server in that case since a DNS SRV lookup for example.com would not
|
||||
* point to the local testing server.
|
||||
*
|
||||
* @param host the host where the XMPP server is running.
|
||||
* @param port the port where the XMPP is listening.
|
||||
* @param serviceName the name of the service provided by an XMPP server.
|
||||
*/
|
||||
public ConnectionConfiguration(String host, int port, String serviceName) {
|
||||
initHostAddresses(host, port);
|
||||
init(serviceName, ProxyInfo.forDefaultProxy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration using the specified host, port and
|
||||
* service name. This is useful for manually overriding the DNS SRV lookup
|
||||
* process that's used with the {@link #ConnectionConfiguration(String)}
|
||||
* constructor. For example, say that an XMPP server is running at localhost
|
||||
* in an internal network on port 5222 but is configured to think that it's
|
||||
* "example.com" for testing purposes. This constructor is necessary to connect
|
||||
* to the server in that case since a DNS SRV lookup for example.com would not
|
||||
* point to the local testing server.
|
||||
*
|
||||
* @param host the host where the XMPP server is running.
|
||||
* @param port the port where the XMPP is listening.
|
||||
* @param serviceName the name of the service provided by an XMPP server.
|
||||
* @param proxy the proxy through which XMPP is to be connected
|
||||
*/
|
||||
public ConnectionConfiguration(String host, int port, String serviceName, ProxyInfo proxy) {
|
||||
initHostAddresses(host, port);
|
||||
init(serviceName, proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration for a connection that will connect
|
||||
* to the desired host and port.
|
||||
*
|
||||
* @param host the host where the XMPP server is running.
|
||||
* @param port the port where the XMPP is listening.
|
||||
*/
|
||||
public ConnectionConfiguration(String host, int port) {
|
||||
initHostAddresses(host, port);
|
||||
init(host, ProxyInfo.forDefaultProxy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ConnectionConfiguration for a connection that will connect
|
||||
* to the desired host and port with desired proxy.
|
||||
*
|
||||
* @param host the host where the XMPP server is running.
|
||||
* @param port the port where the XMPP is listening.
|
||||
* @param proxy the proxy through which XMPP is to be connected
|
||||
*/
|
||||
public ConnectionConfiguration(String host, int port, ProxyInfo proxy) {
|
||||
initHostAddresses(host, port);
|
||||
init(host, proxy);
|
||||
}
|
||||
|
||||
protected void init(String serviceName, ProxyInfo proxy) {
|
||||
if (StringUtils.isEmpty(serviceName)) {
|
||||
throw new IllegalArgumentException("serviceName must not be the empty String");
|
||||
protected ConnectionConfiguration(ConnectionConfigurationBuilder<?,?> builder) {
|
||||
if (builder.username != null) {
|
||||
// Do partial version of nameprep on the username.
|
||||
username = builder.username.toLowerCase(Locale.US).trim();
|
||||
} else {
|
||||
username = null;
|
||||
}
|
||||
password = builder.password;
|
||||
callbackHandler = builder.callbackHandler;
|
||||
if (callbackHandler == null && (password == null || username == null) && !builder.anonymous) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must provide either a username and password, a callback handler or set the connection configuration anonymous");
|
||||
}
|
||||
this.serviceName = serviceName;
|
||||
this.proxy = proxy;
|
||||
|
||||
keystorePath = System.getProperty("javax.net.ssl.keyStore");
|
||||
keystoreType = "jks";
|
||||
pkcs11Library = "pkcs11.config";
|
||||
|
||||
//Setting the SocketFactory according to proxy supplied
|
||||
socketFactory = proxy.getSocketFactory();
|
||||
// Resource can be null, this means that the server must provide one
|
||||
resource = builder.resource;
|
||||
|
||||
serviceName = builder.serviceName;
|
||||
if (serviceName == null) {
|
||||
throw new IllegalArgumentException("Must provide XMPP service name");
|
||||
}
|
||||
host = builder.host;
|
||||
port = builder.port;
|
||||
|
||||
proxy = builder.proxy;
|
||||
if (proxy != null) {
|
||||
if (builder.socketFactory != null) {
|
||||
throw new IllegalArgumentException("Can not use proxy together with custom socket factory");
|
||||
}
|
||||
socketFactory = proxy.getSocketFactory();
|
||||
} else {
|
||||
socketFactory = builder.socketFactory;
|
||||
}
|
||||
|
||||
securityMode = builder.securityMode;
|
||||
keystoreType = builder.keystoreType;
|
||||
keystorePath = builder.keystorePath;
|
||||
pkcs11Library = builder.pkcs11Library;
|
||||
customSSLContext = builder.customSSLContext;
|
||||
enabledSSLProtocols = builder.enabledSSLProtocols;
|
||||
enabledSSLCiphers = builder.enabledSSLCiphers;
|
||||
hostnameVerifier = builder.hostnameVerifier;
|
||||
sendPresence = builder.sendPresence;
|
||||
rosterLoadedAtLogin = builder.rosterLoadedAtLogin;
|
||||
legacySessionDisabled = builder.legacySessionDisabled;
|
||||
rosterStore = builder.rosterStore;
|
||||
debuggerEnabled = builder.debuggerEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the server name, also known as XMPP domain of the target server.
|
||||
*
|
||||
* @param serviceName the XMPP domain of the target server.
|
||||
*/
|
||||
void setServiceName(String serviceName) {
|
||||
serviceName = XmppStringUtils.parseDomain(serviceName);
|
||||
this.serviceName = serviceName;
|
||||
public boolean isAnonymous() {
|
||||
return username == null && callbackHandler == null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,16 +165,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return securityMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the TLS security mode used when making the connection. By default,
|
||||
* the mode is {@link SecurityMode#enabled}.
|
||||
*
|
||||
* @param securityMode the security mode.
|
||||
*/
|
||||
public void setSecurityMode(SecurityMode securityMode) {
|
||||
this.securityMode = securityMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retuns the path to the keystore file. The key store file contains the
|
||||
* certificates that may be used to authenticate the client to the server,
|
||||
|
@ -260,17 +176,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return keystorePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path to the keystore file. The key store file contains the
|
||||
* certificates that may be used to authenticate the client to the server,
|
||||
* in the event the server requests or requires it.
|
||||
*
|
||||
* @param keystorePath the path to the keystore file.
|
||||
*/
|
||||
public void setKeystorePath(String keystorePath) {
|
||||
this.keystorePath = keystorePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the keystore type, or <tt>null</tt> if it's not set.
|
||||
*
|
||||
|
@ -280,16 +185,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return keystoreType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the keystore type.
|
||||
*
|
||||
* @param keystoreType the keystore type.
|
||||
*/
|
||||
public void setKeystoreType(String keystoreType) {
|
||||
this.keystoreType = keystoreType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the PKCS11 library file location, needed when the
|
||||
* Keystore type is PKCS11.
|
||||
|
@ -301,17 +196,7 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the PKCS11 library file location, needed when the
|
||||
* Keystore type is PKCS11
|
||||
*
|
||||
* @param pkcs11Library the path to the PKCS11 library file
|
||||
*/
|
||||
public void setPKCS11Library(String pkcs11Library) {
|
||||
this.pkcs11Library = pkcs11Library;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom SSLContext previously set with {@link #setCustomSSLContext(SSLContext)} for
|
||||
* Gets the custom SSLContext previously set with {@link ConnectionConfigurationBuilder#setCustomSSLContext(SSLContext)} for
|
||||
* SSL sockets. This is null by default.
|
||||
*
|
||||
* @return the custom SSLContext or null.
|
||||
|
@ -320,28 +205,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return this.customSSLContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom SSLContext for creating SSL sockets.
|
||||
* <p>
|
||||
* For more information on how to create a SSLContext see <a href=
|
||||
* "http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#X509TrustManager"
|
||||
* >Java Secure Socket Extension (JSEE) Reference Guide: Creating Your Own X509TrustManager</a>
|
||||
*
|
||||
* @param context the custom SSLContext for new sockets
|
||||
*/
|
||||
public void setCustomSSLContext(SSLContext context) {
|
||||
this.customSSLContext = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enabled SSL/TLS protocols.
|
||||
*
|
||||
* @param enabledSSLProtocols
|
||||
*/
|
||||
public void setEnabledSSLProtocols(String[] enabledSSLProtocols) {
|
||||
this.enabledSSLProtocols = enabledSSLProtocols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enabled SSL/TLS protocols.
|
||||
*
|
||||
|
@ -351,15 +214,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return enabledSSLProtocols;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enabled SSL/TLS ciphers.
|
||||
*
|
||||
* @param enabledSSLCiphers the enabled SSL/TLS ciphers
|
||||
*/
|
||||
public void setEnabledSSLCiphers(String[] enabledSSLCiphers) {
|
||||
this.enabledSSLCiphers = enabledSSLCiphers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enabled SSL/TLS ciphers.
|
||||
*
|
||||
|
@ -369,16 +223,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return enabledSSLCiphers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HostnameVerifier used to verify the hostname of SSLSockets used by XMPP connections
|
||||
* created with this ConnectionConfiguration.
|
||||
*
|
||||
* @param verifier
|
||||
*/
|
||||
public void setHostnameVerifier(HostnameVerifier verifier) {
|
||||
hostnameVerifier = verifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configured HostnameVerifier of this ConnectionConfiguration or the Smack default
|
||||
* HostnameVerifier configured with
|
||||
|
@ -392,30 +236,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return SmackConfiguration.getDefaultHostnameVerifier();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the connection is going to use stream compression. Stream compression
|
||||
* will be requested after TLS was established (if TLS was enabled) and only if the server
|
||||
* offered stream compression. With stream compression network traffic can be reduced
|
||||
* up to 90%. By default compression is disabled.
|
||||
*
|
||||
* @return true if the connection is going to use stream compression.
|
||||
*/
|
||||
public boolean isCompressionEnabled() {
|
||||
return compressionEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the connection is going to use stream compression. Stream compression
|
||||
* will be requested after TLS was established (if TLS was enabled) and only if the server
|
||||
* offered stream compression. With stream compression network traffic can be reduced
|
||||
* up to 90%. By default compression is disabled.
|
||||
*
|
||||
* @param compressionEnabled if the connection is going to use stream compression.
|
||||
*/
|
||||
public void setCompressionEnabled(boolean compressionEnabled) {
|
||||
this.compressionEnabled = compressionEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the new connection about to be establish is going to be debugged. By
|
||||
* default the value of {@link SmackConfiguration#DEBUG_ENABLED} is used.
|
||||
|
@ -426,38 +246,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return debuggerEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the new connection about to be establish is going to be debugged. By
|
||||
* default the value of {@link SmackConfiguration#DEBUG_ENABLED} is used.
|
||||
*
|
||||
* @param debuggerEnabled if the new connection about to be establish is going to be debugged.
|
||||
*/
|
||||
public void setDebuggerEnabled(boolean debuggerEnabled) {
|
||||
this.debuggerEnabled = debuggerEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket factory used to create new xmppConnection sockets.
|
||||
* This is useful when connecting through SOCKS5 proxies.
|
||||
*
|
||||
* @param socketFactory used to create new sockets.
|
||||
*/
|
||||
public void setSocketFactory(SocketFactory socketFactory) {
|
||||
this.socketFactory = socketFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if an initial available presence will be sent to the server. By default
|
||||
* an available presence will be sent to the server indicating that this presence
|
||||
* is not online and available to receive messages. If you want to log in without
|
||||
* being 'noticed' then pass a <tt>false</tt> value.
|
||||
*
|
||||
* @param sendPresence true if an initial available presence will be sent while logging in.
|
||||
*/
|
||||
public void setSendPresence(boolean sendPresence) {
|
||||
this.sendPresence = sendPresence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the roster will be loaded from the server when logging in. This
|
||||
* is the common behaviour for clients but sometimes clients may want to differ this
|
||||
|
@ -469,17 +257,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return rosterLoadedAtLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the roster will be loaded from the server when logging in. This
|
||||
* is the common behaviour for clients but sometimes clients may want to differ this
|
||||
* or just never do it if not interested in rosters.
|
||||
*
|
||||
* @param rosterLoadedAtLogin if the roster will be loaded from the server when logging in.
|
||||
*/
|
||||
public void setRosterLoadedAtLogin(boolean rosterLoadedAtLogin) {
|
||||
this.rosterLoadedAtLogin = rosterLoadedAtLogin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a {@link Session} will be requested on login if the server
|
||||
* supports it. Although this was mandatory on RFC 3921, RFC 6120/6121 don't
|
||||
|
@ -491,17 +268,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return legacySessionDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if a {@link Session} will be requested on login if the server supports
|
||||
* it. Although this was mandatory on RFC 3921, RFC 6120/6121 don't even
|
||||
* mention this part of the protocol.
|
||||
*
|
||||
* @param legacySessionDisabled if a session has to be requested when logging in.
|
||||
*/
|
||||
public void setLegacySessionDisabled(boolean legacySessionDisabled) {
|
||||
this.legacySessionDisabled = legacySessionDisabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a CallbackHandler to obtain information, such as the password or
|
||||
* principal information during the SASL authentication. A CallbackHandler
|
||||
|
@ -515,19 +281,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return callbackHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a CallbackHandler to obtain information, such as the password or
|
||||
* principal information during the SASL authentication. A CallbackHandler
|
||||
* will be used <b>ONLY</b> if no password was specified during the login while
|
||||
* using SASL authentication.
|
||||
*
|
||||
* @param callbackHandler to obtain information, such as the password or
|
||||
* principal information during the SASL authentication.
|
||||
*/
|
||||
public void setCallbackHandler(CallbackHandler callbackHandler) {
|
||||
this.callbackHandler = callbackHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the socket factory used to create new xmppConnection sockets.
|
||||
* This is useful when connecting through SOCKS5 proxies.
|
||||
|
@ -538,17 +291,6 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return this.socketFactory;
|
||||
}
|
||||
|
||||
public List<HostAddress> getHostAddresses() {
|
||||
return Collections.unmodifiableList(hostAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permanent roster store
|
||||
*/
|
||||
public void setRosterStore(RosterStore store) {
|
||||
rosterStore = store;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the permanent roster store
|
||||
*/
|
||||
|
@ -620,25 +362,319 @@ public class ConnectionConfiguration implements Cloneable {
|
|||
return sendPresence;
|
||||
}
|
||||
|
||||
void setLoginInfo(String username, String password, String resource) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.resource = resource;
|
||||
/**
|
||||
* Returns true if the connection is going to use stream compression. Stream compression
|
||||
* will be requested after TLS was established (if TLS was enabled) and only if the server
|
||||
* offered stream compression. With stream compression network traffic can be reduced
|
||||
* up to 90%. By default compression is disabled.
|
||||
*
|
||||
* @return true if the connection is going to use stream compression.
|
||||
*/
|
||||
public boolean isCompressionEnabled() {
|
||||
// Compression for non-TCP connections is always disabled
|
||||
return false;
|
||||
}
|
||||
|
||||
void maybeResolveDns() throws Exception {
|
||||
if (!useDnsSrvRr) return;
|
||||
hostAddresses = DNSUtil.resolveXMPPDomain(serviceName);
|
||||
}
|
||||
/**
|
||||
* A builder for XMPP connection configurations.
|
||||
* <p>
|
||||
* This is an abstract class that uses the builder design pattern and the "getThis() trick" to recover the type of
|
||||
* the builder in a class hierarchies with a self-referential generic supertype. Otherwise chaining of build
|
||||
* instructions from the superclasses followed by build instructions of a sublcass would not be possible, because
|
||||
* the superclass build instructions would return the builder of the superclass and not the one of the subclass. You
|
||||
* can read more about it a Angelika Langer's Generics FAQ, especially the entry <a
|
||||
* href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206">What is the
|
||||
* "getThis()" trick?</a>.
|
||||
* </p>
|
||||
*
|
||||
* @param <B> the builder type parameter.
|
||||
* @param <C> the resulting connection configuration type parameter.
|
||||
*/
|
||||
public static abstract class ConnectionConfigurationBuilder<B extends ConnectionConfigurationBuilder<B, C>, C extends ConnectionConfiguration> {
|
||||
private SecurityMode securityMode = SecurityMode.enabled;
|
||||
private String keystorePath = System.getProperty("javax.net.ssl.keyStore");
|
||||
private String keystoreType = "jks";
|
||||
private String pkcs11Library = "pkcs11.config";
|
||||
private SSLContext customSSLContext;
|
||||
private String[] enabledSSLProtocols;
|
||||
private String[] enabledSSLCiphers;
|
||||
private HostnameVerifier hostnameVerifier;
|
||||
private String username;
|
||||
private String password;
|
||||
private boolean anonymous;
|
||||
private String resource = "Smack";
|
||||
private boolean sendPresence = true;
|
||||
private boolean rosterLoadedAtLogin = true;
|
||||
private boolean legacySessionDisabled = false;
|
||||
private RosterStore rosterStore;
|
||||
private ProxyInfo proxy;
|
||||
private CallbackHandler callbackHandler;
|
||||
private boolean debuggerEnabled = SmackConfiguration.DEBUG_ENABLED;
|
||||
private SocketFactory socketFactory;
|
||||
private String serviceName;
|
||||
private String host;
|
||||
private int port = 5222;
|
||||
|
||||
private void initHostAddresses(String host, int port) {
|
||||
if (StringUtils.isEmpty(host)) {
|
||||
throw new IllegalArgumentException("host must not be the empty String");
|
||||
protected ConnectionConfigurationBuilder() {
|
||||
}
|
||||
hostAddresses = new ArrayList<HostAddress>(1);
|
||||
HostAddress hostAddress;
|
||||
hostAddress = new HostAddress(host, port);
|
||||
hostAddresses.add(hostAddress);
|
||||
useDnsSrvRr = false;
|
||||
|
||||
/**
|
||||
* Set the XMPP entities username and password.
|
||||
* <p>
|
||||
* The username is the localpart of the entities JID, e.g. <code>localpart@example.org</code>. In order to
|
||||
* create an anonymous connection, call {@link #makeAnonymous} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setUsernameAndPassword(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a configuration for a anonymous XMPP connection.
|
||||
* <p>
|
||||
* Anonyous connections don't provide a username or other authentification credentials like a password. Instead
|
||||
* the XMPP server, if supporting anonymous connections, will assign a username to the client.
|
||||
* </p>
|
||||
*
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B makeAnonymous() {
|
||||
this.username = null;
|
||||
this.password = null;
|
||||
anonymous = true;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the service name of this XMPP service (i.e., the XMPP domain).
|
||||
*
|
||||
* @param serviceName the service name
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setServiceName(String serviceName) {
|
||||
this.serviceName = serviceName;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource to use.
|
||||
* <p>
|
||||
* If <code>resource</code> is <code>null</code>, then the server will automatically create a resource for the
|
||||
* client. Default resource is "Smack".
|
||||
* </p>
|
||||
*
|
||||
* @param resource the resource to use.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setResource(String resource) {
|
||||
this.resource = resource;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public B setHost(String host) {
|
||||
this.host = host;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public B setPort(int port) {
|
||||
this.port = port;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a CallbackHandler to obtain information, such as the password or
|
||||
* principal information during the SASL authentication. A CallbackHandler
|
||||
* will be used <b>ONLY</b> if no password was specified during the login while
|
||||
* using SASL authentication.
|
||||
*
|
||||
* @param callbackHandler to obtain information, such as the password or
|
||||
* principal information during the SASL authentication.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setCallbackHandler(CallbackHandler callbackHandler) {
|
||||
this.callbackHandler = callbackHandler;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the TLS security mode used when making the connection. By default,
|
||||
* the mode is {@link SecurityMode#enabled}.
|
||||
*
|
||||
* @param securityMode the security mode.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setSecurityMode(SecurityMode securityMode) {
|
||||
this.securityMode = securityMode;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the path to the keystore file. The key store file contains the
|
||||
* certificates that may be used to authenticate the client to the server,
|
||||
* in the event the server requests or requires it.
|
||||
*
|
||||
* @param keystorePath the path to the keystore file.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setKeystorePath(String keystorePath) {
|
||||
this.keystorePath = keystorePath;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the keystore type.
|
||||
*
|
||||
* @param keystoreType the keystore type.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setKeystoreType(String keystoreType) {
|
||||
this.keystoreType = keystoreType;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the PKCS11 library file location, needed when the
|
||||
* Keystore type is PKCS11
|
||||
*
|
||||
* @param pkcs11Library the path to the PKCS11 library file.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setPKCS11Library(String pkcs11Library) {
|
||||
this.pkcs11Library = pkcs11Library;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a custom SSLContext for creating SSL sockets.
|
||||
* <p>
|
||||
* For more information on how to create a SSLContext see <a href=
|
||||
* "http://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#X509TrustManager"
|
||||
* >Java Secure Socket Extension (JSEE) Reference Guide: Creating Your Own X509TrustManager</a>
|
||||
*
|
||||
* @param context the custom SSLContext for new sockets.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setCustomSSLContext(SSLContext context) {
|
||||
this.customSSLContext = context;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enabled SSL/TLS protocols.
|
||||
*
|
||||
* @param enabledSSLProtocols
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setEnabledSSLProtocols(String[] enabledSSLProtocols) {
|
||||
this.enabledSSLProtocols = enabledSSLProtocols;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enabled SSL/TLS ciphers.
|
||||
*
|
||||
* @param enabledSSLCiphers the enabled SSL/TLS ciphers
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setEnabledSSLCiphers(String[] enabledSSLCiphers) {
|
||||
this.enabledSSLCiphers = enabledSSLCiphers;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the HostnameVerifier used to verify the hostname of SSLSockets used by XMPP connections
|
||||
* created with this ConnectionConfiguration.
|
||||
*
|
||||
* @param verifier
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setHostnameVerifier(HostnameVerifier verifier) {
|
||||
hostnameVerifier = verifier;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if a {@link Session} will be requested on login if the server supports
|
||||
* it. Although this was mandatory on RFC 3921, RFC 6120/6121 don't even
|
||||
* mention this part of the protocol.
|
||||
*
|
||||
* @param legacySessionDisabled if a session has to be requested when logging in.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setLegacySessionDisabled(boolean legacySessionDisabled) {
|
||||
this.legacySessionDisabled = legacySessionDisabled;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the roster will be loaded from the server when logging in. This
|
||||
* is the common behaviour for clients but sometimes clients may want to differ this
|
||||
* or just never do it if not interested in rosters.
|
||||
*
|
||||
* @param rosterLoadedAtLogin if the roster will be loaded from the server when logging in.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setRosterLoadedAtLogin(boolean rosterLoadedAtLogin) {
|
||||
this.rosterLoadedAtLogin = rosterLoadedAtLogin;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if an initial available presence will be sent to the server. By default
|
||||
* an available presence will be sent to the server indicating that this presence
|
||||
* is not online and available to receive messages. If you want to log in without
|
||||
* being 'noticed' then pass a <tt>false</tt> value.
|
||||
*
|
||||
* @param sendPresence true if an initial available presence will be sent while logging in.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setSendPresence(boolean sendPresence) {
|
||||
this.sendPresence = sendPresence;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the permanent roster store.
|
||||
*
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setRosterStore(RosterStore store) {
|
||||
rosterStore = store;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the new connection about to be establish is going to be debugged. By
|
||||
* default the value of {@link SmackConfiguration#DEBUG_ENABLED} is used.
|
||||
*
|
||||
* @param debuggerEnabled if the new connection about to be establish is going to be debugged.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setDebuggerEnabled(boolean debuggerEnabled) {
|
||||
this.debuggerEnabled = debuggerEnabled;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the socket factory used to create new xmppConnection sockets.
|
||||
* This is useful when connecting through SOCKS5 proxies.
|
||||
*
|
||||
* @param socketFactory used to create new sockets.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public B setSocketFactory(SocketFactory socketFactory) {
|
||||
this.socketFactory = socketFactory;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public abstract C build();
|
||||
|
||||
protected abstract B getThis();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Set;
|
|||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.ConnectionConfigurationBuilder;
|
||||
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
||||
import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory;
|
||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||
|
@ -267,7 +268,7 @@ public final class SmackConfiguration {
|
|||
* Set the default HostnameVerifier that will be used by XMPP connections to verify the hostname
|
||||
* of a TLS certificate. XMPP connections are able to overwrite this settings by supplying a
|
||||
* HostnameVerifier in their ConnecitonConfiguration with
|
||||
* {@link ConnectionConfiguration#setHostnameVerifier(HostnameVerifier)}.
|
||||
* {@link ConnectionConfigurationBuilder#setHostnameVerifier(HostnameVerifier)}.
|
||||
*/
|
||||
public static void setDefaultHostnameVerifier(HostnameVerifier verifier) {
|
||||
defaultHostnameVerififer = verifier;
|
||||
|
|
|
@ -30,7 +30,7 @@ import javax.net.ssl.SSLSocket;
|
|||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.ConnectionConfigurationBuilder;
|
||||
import org.jivesoftware.smack.SmackException.SecurityNotPossibleException;
|
||||
|
||||
|
||||
|
@ -53,10 +53,11 @@ public class TLSUtils {
|
|||
* This method requires the underlying OS to support all of TLSv1.2 , 1.1 and 1.0.
|
||||
* </p>
|
||||
*
|
||||
* @param conf the configuration to apply this setting to
|
||||
* @param builder the configuration builder to apply this setting to
|
||||
*/
|
||||
public static void setTLSOnly(ConnectionConfiguration conf) {
|
||||
conf.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1 });
|
||||
public static <B extends ConnectionConfigurationBuilder<B,?>> B setTLSOnly(B builder) {
|
||||
builder.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1 });
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,10 +70,11 @@ public class TLSUtils {
|
|||
* TLSv1.1.
|
||||
* </p>
|
||||
*
|
||||
* @param conf the configuration to apply this setting to
|
||||
* @param builder the configuration builder to apply this setting to
|
||||
*/
|
||||
public static void setSSLv3AndTLSOnly(ConnectionConfiguration conf) {
|
||||
conf.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1, PROTO_SSL3 });
|
||||
public static <B extends ConnectionConfigurationBuilder<B,?>> B setSSLv3AndTLSOnly(B builder) {
|
||||
builder.setEnabledSSLProtocols(new String[] { PROTO_TLSV1_2, PROTO_TLSV1_1, PROTO_TLSV1, PROTO_SSL3 });
|
||||
return builder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -82,14 +84,15 @@ public class TLSUtils {
|
|||
* {@link AcceptAllTrustManager}. Only use this method if you understand the implications.
|
||||
* </p>
|
||||
*
|
||||
* @param conf
|
||||
* @param builder
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws KeyManagementException
|
||||
*/
|
||||
public static void acceptAllCertificates(ConnectionConfiguration conf) throws NoSuchAlgorithmException, KeyManagementException {
|
||||
public static <B extends ConnectionConfigurationBuilder<B,?>> B acceptAllCertificates(B builder) throws NoSuchAlgorithmException, KeyManagementException {
|
||||
SSLContext context = SSLContext.getInstance(TLS);
|
||||
context.init(null, new TrustManager[] { new AcceptAllTrustManager() }, new SecureRandom());
|
||||
conf.setCustomSSLContext(context);
|
||||
builder.setCustomSSLContext(context);
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static void setEnabledProtocolsAndCiphers(final SSLSocket sslSocket,
|
||||
|
|
|
@ -354,7 +354,7 @@ public class ChatConnectionTest {
|
|||
|
||||
try {
|
||||
con.connect();
|
||||
con.login("me", "secret");
|
||||
con.login();
|
||||
} catch (Exception e) {
|
||||
// No need for handling in a dummy connection.
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.concurrent.BlockingQueue;
|
|||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.ConnectionConfigurationBuilder;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smack.packet.PlainStreamElement;
|
||||
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||
|
@ -53,8 +54,13 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
|
||||
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
|
||||
|
||||
public static ConnectionConfigurationBuilder<?,?> getDummyConfigurationBuilder() {
|
||||
return DummyConnectionConfiguration.builder().setServiceName("example.org").setUsernameAndPassword("dummy",
|
||||
"dummypass");
|
||||
}
|
||||
|
||||
public DummyConnection() {
|
||||
this(new ConnectionConfiguration("example.com"));
|
||||
this(getDummyConfigurationBuilder().build());
|
||||
}
|
||||
|
||||
public DummyConnection(ConnectionConfiguration configuration) {
|
||||
|
@ -63,12 +69,16 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
|
||||
listener.connectionCreated(this);
|
||||
}
|
||||
connected = true;
|
||||
user = "dummy@" + config.getServiceName() + "/Test";
|
||||
user = config.getUsername()
|
||||
+ "@"
|
||||
+ config.getServiceName()
|
||||
+ "/"
|
||||
+ (config.getResource() != null ? config.getResource() : "Test");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connectInternal() {
|
||||
connected = true;
|
||||
connectionID = "dummy-" + new Random(new Date().getTime()).nextInt();
|
||||
|
||||
if (reconnect) {
|
||||
|
@ -130,19 +140,13 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void login(String username, String password, String resource)
|
||||
protected void loginNonAnonymously()
|
||||
throws XMPPException {
|
||||
if (!isConnected()) {
|
||||
throw new IllegalStateException("Not connected to server.");
|
||||
}
|
||||
if (isAuthenticated()) {
|
||||
throw new IllegalStateException("Already logged in to server.");
|
||||
}
|
||||
user = (username != null ? username : "dummy")
|
||||
user = config.getUsername()
|
||||
+ "@"
|
||||
+ config.getServiceName()
|
||||
+ "/"
|
||||
+ (resource != null ? resource : "Test");
|
||||
+ (config.getResource() != null ? config.getResource() : "Test");
|
||||
roster = new Roster(this);
|
||||
anonymous = false;
|
||||
authenticated = true;
|
||||
|
@ -226,4 +230,32 @@ public class DummyConnection extends AbstractXMPPConnection {
|
|||
|
||||
invokePacketCollectorsAndNotifyRecvListeners(packet);
|
||||
}
|
||||
|
||||
public static class DummyConnectionConfiguration extends ConnectionConfiguration {
|
||||
protected DummyConnectionConfiguration(DummyConnectionConfigurationBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static DummyConnectionConfigurationBuilder builder() {
|
||||
return new DummyConnectionConfigurationBuilder();
|
||||
}
|
||||
|
||||
public static class DummyConnectionConfigurationBuilder
|
||||
extends
|
||||
ConnectionConfigurationBuilder<DummyConnectionConfigurationBuilder, DummyConnectionConfiguration> {
|
||||
|
||||
private DummyConnectionConfigurationBuilder() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public DummyConnectionConfiguration build() {
|
||||
return new DummyConnectionConfiguration(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DummyConnectionConfigurationBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public class RosterTest {
|
|||
|
||||
connection = new DummyConnection();
|
||||
connection.connect();
|
||||
connection.login("rostertest", "secret");
|
||||
connection.login();
|
||||
rosterListener = new TestRosterListener();
|
||||
connection.getRoster().addRosterListener(rosterListener);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
|||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration.ConnectionConfigurationBuilder;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
|
@ -64,12 +65,12 @@ public class RosterVersioningTest {
|
|||
DirectoryRosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder("store"));
|
||||
populateStore(store);
|
||||
|
||||
ConnectionConfiguration conf = new ConnectionConfiguration("dummy");
|
||||
conf.setRosterStore(store);
|
||||
connection = new DummyConnection(conf);
|
||||
ConnectionConfigurationBuilder<?, ?> builder = DummyConnection.getDummyConfigurationBuilder();
|
||||
builder.setRosterStore(store);
|
||||
connection = new DummyConnection(builder.build());
|
||||
connection.connect();
|
||||
|
||||
connection.login("rostertest", "secret");
|
||||
connection.login();
|
||||
}
|
||||
|
||||
@After
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue