Smack/smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java

238 lines
7.3 KiB
Java

/**
*
* Copyright 2010 Jive Software.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smack;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.Nonza;
import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jxmpp.jid.EntityFullJid;
import org.jxmpp.jid.JidTestUtil;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.jid.parts.Resourcepart;
import org.jxmpp.stringprep.XmppStringprepException;
/**
* A dummy implementation of {@link XMPPConnection}, intended to be used during
* unit tests.
*
* Instances store any packets that are delivered to be send using the
* {@link #sendStanza(Stanza)} method in a blocking queue. The content of this queue
* can be inspected using {@link #getSentPacket()}. Typically these queues are
* used to retrieve a message that was generated by the client.
*
* Packets that should be processed by the client to simulate a received stanza
* can be delivered using the {@linkplain #processStanza(Stanza)} method.
* It invokes the registered stanza(/packet) interceptors and listeners.
*
* @see XMPPConnection
* @author Guenther Niess
*/
public class DummyConnection extends AbstractXMPPConnection {
private boolean reconnect = false;
private final BlockingQueue<TopLevelStreamElement> queue = new LinkedBlockingQueue<TopLevelStreamElement>();
public static ConnectionConfiguration.Builder<?,?> getDummyConfigurationBuilder() {
return DummyConnectionConfiguration.builder().setXmppDomain(JidTestUtil.EXAMPLE_ORG).setUsernameAndPassword("dummy",
"dummypass");
}
public DummyConnection() {
this(getDummyConfigurationBuilder().build());
}
private EntityFullJid getUserJid() {
try {
return JidCreate.entityFullFrom(config.getUsername()
+ "@"
+ config.getXMPPServiceDomain()
+ "/"
+ (config.getResource() != null ? config.getResource() : "Test"));
}
catch (XmppStringprepException e) {
throw new IllegalStateException(e);
}
}
public DummyConnection(ConnectionConfiguration configuration) {
super(configuration);
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
listener.connectionCreated(this);
}
user = getUserJid();
}
@Override
protected void connectInternal() {
connected = true;
saslFeatureReceived.reportSuccess();
tlsHandled.reportSuccess();
streamId = "dummy-" + new Random(new Date().getTime()).nextInt();
if (reconnect) {
notifyReconnection();
}
}
@Override
protected void shutdown() {
user = null;
authenticated = false;
callConnectionClosedListener();
reconnect = true;
}
@Override
public boolean isSecureConnection() {
return false;
}
@Override
public boolean isUsingCompression() {
return false;
}
@Override
protected void loginInternal(String username, String password, Resourcepart resource)
throws XMPPException {
user = getUserJid();
authenticated = true;
}
@Override
public void sendNonza(Nonza element) {
queue.add(element);
}
@Override
protected void sendStanzaInternal(Stanza packet) {
queue.add(packet);
}
/**
* Returns the number of packets that's sent through {@link #sendStanza(Stanza)} and
* that has not been returned by {@link #getSentPacket()}.
*
* @return the number of packets which are in the queue.
*/
public int getNumberOfSentPackets() {
return queue.size();
}
/**
* Returns the first stanza(/packet) that's sent through {@link #sendStanza(Stanza)}
* and that has not been returned by earlier calls to this method.
*
* @return a sent packet.
*/
public <P extends TopLevelStreamElement> P getSentPacket() {
return getSentPacket(5 * 60);
}
/**
* Returns the first stanza(/packet) that's sent through {@link #sendStanza(Stanza)}
* and that has not been returned by earlier calls to this method. This
* method will block for up to the specified number of seconds if no packets
* have been sent yet.
*
* @return a sent packet.
*/
@SuppressWarnings("unchecked")
public <P extends TopLevelStreamElement> P getSentPacket(int wait) {
try {
return (P) queue.poll(wait, TimeUnit.SECONDS);
}
catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
/**
* Processes a stanza(/packet) through the installed stanza(/packet) collectors and listeners
* and letting them examine the stanza(/packet) to see if they are a match with the
* filter.
*
* @param packet the stanza(/packet) to process.
*/
@Override
public void processStanza(Stanza packet) {
invokeStanzaCollectorsAndNotifyRecvListeners(packet);
}
/**
* Enable stream feature.
*
* @param streamFeature the stream feature.
* @since 4.2
*/
public void enableStreamFeature(ExtensionElement streamFeature) {
addStreamFeature(streamFeature);
}
public static DummyConnection newConnectedDummyConnection() {
DummyConnection dummyConnection = new DummyConnection();
try {
dummyConnection.connect();
dummyConnection.login();
}
catch (InterruptedException | SmackException | IOException | XMPPException e) {
throw new IllegalStateException(e);
}
return dummyConnection;
}
public static class DummyConnectionConfiguration extends ConnectionConfiguration {
protected DummyConnectionConfiguration(Builder builder) {
super(builder);
}
public static Builder builder() {
return new Builder();
}
public static final class Builder
extends
ConnectionConfiguration.Builder<Builder, DummyConnectionConfiguration> {
private Builder() {
}
@Override
public DummyConnectionConfiguration build() {
return new DummyConnectionConfiguration(this);
}
@Override
protected Builder getThis() {
return this;
}
}
}
}