mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Merge flowdalic/master
This commit is contained in:
commit
9712dc1df7
40 changed files with 714 additions and 544 deletions
|
@ -53,7 +53,7 @@ service=example.org
|
||||||
```bash
|
```bash
|
||||||
service=example.org
|
service=example.org
|
||||||
serviceTlsPin=CERTSHA256:2F:92:C9:4D:30:58:E1:05:21:9A:57:59:5F:6E:25:9A:0F:BF:FF:64:1A:C3:4B:EC:06:7D:4A:6F:0A:D5:21:85
|
serviceTlsPin=CERTSHA256:2F:92:C9:4D:30:58:E1:05:21:9A:57:59:5F:6E:25:9A:0F:BF:FF:64:1A:C3:4B:EC:06:7D:4A:6F:0A:D5:21:85
|
||||||
debug=true
|
debugger=console
|
||||||
```
|
```
|
||||||
|
|
||||||
### Framework properties
|
### Framework properties
|
||||||
|
@ -72,7 +72,7 @@ debug=true
|
||||||
| accountTwoPassword | Password of the second XMPP account |
|
| accountTwoPassword | Password of the second XMPP account |
|
||||||
| accountThreeUsername | Username of the third XMPP account |
|
| accountThreeUsername | Username of the third XMPP account |
|
||||||
| accountThreePassword | Password of the third XMPP account |
|
| accountThreePassword | Password of the third XMPP account |
|
||||||
| debug | 'true' to enable debug output |
|
| debugger | 'console' for console debugger, 'enhanced' for the enhanced debugger |
|
||||||
| enabledTests | List of enabled tests |
|
| enabledTests | List of enabled tests |
|
||||||
| disabledTests | List of disabled tests |
|
| disabledTests | List of disabled tests |
|
||||||
| testPackages | List of packages with tests |
|
| testPackages | List of packages with tests |
|
||||||
|
|
|
@ -16,9 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.debugger.android;
|
package org.jivesoftware.smackx.debugger.android;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.debugger.AbstractDebugger;
|
import org.jivesoftware.smack.debugger.AbstractDebugger;
|
||||||
|
|
||||||
|
@ -37,8 +34,8 @@ import android.util.Log;
|
||||||
*/
|
*/
|
||||||
public class AndroidDebugger extends AbstractDebugger {
|
public class AndroidDebugger extends AbstractDebugger {
|
||||||
|
|
||||||
public AndroidDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
public AndroidDebugger(XMPPConnection connection) {
|
||||||
super(connection, writer, reader);
|
super(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -161,16 +161,8 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
client.addBOSHClientResponseListener(new BOSHPacketReader());
|
client.addBOSHClientResponseListener(new BOSHPacketReader());
|
||||||
|
|
||||||
// Initialize the debugger
|
// Initialize the debugger
|
||||||
if (config.isDebuggerEnabled()) {
|
if (debugger != null) {
|
||||||
initDebugger();
|
initDebugger();
|
||||||
if (isFirstInitialization) {
|
|
||||||
if (debugger.getReaderListener() != null) {
|
|
||||||
addAsyncStanzaListener(debugger.getReaderListener(), null);
|
|
||||||
}
|
|
||||||
if (debugger.getWriterListener() != null) {
|
|
||||||
addPacketSendingListener(debugger.getWriterListener(), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the session creation request
|
// Send the session creation request
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
import org.jivesoftware.smack.compress.packet.Compress;
|
import org.jivesoftware.smack.compress.packet.Compress;
|
||||||
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||||
|
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
import org.jivesoftware.smack.filter.IQReplyFilter;
|
import org.jivesoftware.smack.filter.IQReplyFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
import org.jivesoftware.smack.filter.StanzaIdFilter;
|
import org.jivesoftware.smack.filter.StanzaIdFilter;
|
||||||
|
@ -178,7 +179,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
/**
|
/**
|
||||||
* The SmackDebugger allows to log and debug XML traffic.
|
* The SmackDebugger allows to log and debug XML traffic.
|
||||||
*/
|
*/
|
||||||
protected SmackDebugger debugger = null;
|
protected final SmackDebugger debugger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Reader which is used for the debugger.
|
* The Reader which is used for the debugger.
|
||||||
|
@ -301,6 +302,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
protected AbstractXMPPConnection(ConnectionConfiguration configuration) {
|
protected AbstractXMPPConnection(ConnectionConfiguration configuration) {
|
||||||
saslAuthentication = new SASLAuthentication(this, configuration);
|
saslAuthentication = new SASLAuthentication(this, configuration);
|
||||||
config = configuration;
|
config = configuration;
|
||||||
|
SmackDebuggerFactory debuggerFactory = configuration.getDebuggerFactory();
|
||||||
|
if (debuggerFactory != null) {
|
||||||
|
debugger = debuggerFactory.create(this);
|
||||||
|
} else {
|
||||||
|
debugger = null;
|
||||||
|
}
|
||||||
// Notify listeners that a new connection has been established
|
// Notify listeners that a new connection has been established
|
||||||
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
|
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
|
||||||
listener.connectionCreated(this);
|
listener.connectionCreated(this);
|
||||||
|
@ -568,7 +575,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
// name we are now logged-in as.
|
// name we are now logged-in as.
|
||||||
// If DEBUG was set to true AFTER the connection was created the debugger
|
// If DEBUG was set to true AFTER the connection was created the debugger
|
||||||
// will be null
|
// will be null
|
||||||
if (config.isDebuggerEnabled() && debugger != null) {
|
if (debugger != null) {
|
||||||
debugger.userHasLogged(user);
|
debugger.userHasLogged(user);
|
||||||
}
|
}
|
||||||
callConnectionAuthenticatedListener(resumed);
|
callConnectionAuthenticatedListener(resumed);
|
||||||
|
@ -872,6 +879,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("javadoc")
|
@SuppressWarnings("javadoc")
|
||||||
protected void firePacketSendingListeners(final Stanza packet) {
|
protected void firePacketSendingListeners(final Stanza packet) {
|
||||||
|
final SmackDebugger debugger = this.debugger;
|
||||||
|
if (debugger != null) {
|
||||||
|
debugger.onOutgoingStreamElement(packet);
|
||||||
|
}
|
||||||
|
|
||||||
final List<StanzaListener> listenersToNotify = new LinkedList<StanzaListener>();
|
final List<StanzaListener> listenersToNotify = new LinkedList<StanzaListener>();
|
||||||
synchronized (sendListeners) {
|
synchronized (sendListeners) {
|
||||||
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
|
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
|
||||||
|
@ -957,20 +969,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
throw new NullPointerException("Reader or writer isn't initialized.");
|
throw new NullPointerException("Reader or writer isn't initialized.");
|
||||||
}
|
}
|
||||||
// If debugging is enabled, we open a window and write out all network traffic.
|
// If debugging is enabled, we open a window and write out all network traffic.
|
||||||
if (config.isDebuggerEnabled()) {
|
if (debugger != null) {
|
||||||
if (debugger == null) {
|
|
||||||
debugger = SmackConfiguration.createDebugger(this, writer, reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debugger == null) {
|
|
||||||
LOGGER.severe("Debugging enabled but could not find debugger class");
|
|
||||||
} else {
|
|
||||||
// Obtain new reader and writer from the existing debugger
|
// Obtain new reader and writer from the existing debugger
|
||||||
reader = debugger.newConnectionReader(reader);
|
reader = debugger.newConnectionReader(reader);
|
||||||
writer = debugger.newConnectionWriter(writer);
|
writer = debugger.newConnectionWriter(writer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
|
@ -1072,6 +1076,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
*/
|
*/
|
||||||
protected void processStanza(final Stanza stanza) throws InterruptedException {
|
protected void processStanza(final Stanza stanza) throws InterruptedException {
|
||||||
assert (stanza != null);
|
assert (stanza != null);
|
||||||
|
|
||||||
|
final SmackDebugger debugger = this.debugger;
|
||||||
|
if (debugger != null) {
|
||||||
|
debugger.onIncomingStreamElement(stanza);
|
||||||
|
}
|
||||||
|
|
||||||
lastStanzaReceived = System.currentTimeMillis();
|
lastStanzaReceived = System.currentTimeMillis();
|
||||||
// Deliver the incoming packet to listeners.
|
// Deliver the incoming packet to listeners.
|
||||||
executorService.executeBlocking(new Runnable() {
|
executorService.executeBlocking(new Runnable() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software.
|
* Copyright 2003-2007 Jive Software, 2017 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.
|
||||||
|
@ -30,6 +30,7 @@ import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
import javax.security.auth.callback.CallbackHandler;
|
import javax.security.auth.callback.CallbackHandler;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
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.jivesoftware.smack.sasl.SASLMechanism;
|
import org.jivesoftware.smack.sasl.SASLMechanism;
|
||||||
|
@ -78,7 +79,7 @@ public abstract class ConnectionConfiguration {
|
||||||
*/
|
*/
|
||||||
private final CallbackHandler callbackHandler;
|
private final CallbackHandler callbackHandler;
|
||||||
|
|
||||||
private final boolean debuggerEnabled;
|
private final SmackDebuggerFactory debuggerFactory;
|
||||||
|
|
||||||
// Holds the socket factory that is used to generate the socket in the connection
|
// Holds the socket factory that is used to generate the socket in the connection
|
||||||
private final SocketFactory socketFactory;
|
private final SocketFactory socketFactory;
|
||||||
|
@ -158,7 +159,7 @@ public abstract class ConnectionConfiguration {
|
||||||
hostnameVerifier = builder.hostnameVerifier;
|
hostnameVerifier = builder.hostnameVerifier;
|
||||||
sendPresence = builder.sendPresence;
|
sendPresence = builder.sendPresence;
|
||||||
legacySessionDisabled = builder.legacySessionDisabled;
|
legacySessionDisabled = builder.legacySessionDisabled;
|
||||||
debuggerEnabled = builder.debuggerEnabled;
|
debuggerFactory = builder.debuggerFactory;
|
||||||
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
|
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
|
||||||
enabledSaslMechanisms = builder.enabledSaslMechanisms;
|
enabledSaslMechanisms = builder.enabledSaslMechanisms;
|
||||||
|
|
||||||
|
@ -281,13 +282,12 @@ public abstract class ConnectionConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the new connection about to be establish is going to be debugged. By
|
* Returns the Smack debugger factory.
|
||||||
* default the value of {@link SmackConfiguration#DEBUG} is used.
|
|
||||||
*
|
*
|
||||||
* @return true if the new connection about to be establish is going to be debugged.
|
* @return the Smack debugger factory or <code>null</code>
|
||||||
*/
|
*/
|
||||||
public boolean isDebuggerEnabled() {
|
public SmackDebuggerFactory getDebuggerFactory() {
|
||||||
return debuggerEnabled;
|
return debuggerFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -519,7 +519,7 @@ public abstract class ConnectionConfiguration {
|
||||||
private boolean legacySessionDisabled = false;
|
private boolean legacySessionDisabled = false;
|
||||||
private ProxyInfo proxy;
|
private ProxyInfo proxy;
|
||||||
private CallbackHandler callbackHandler;
|
private CallbackHandler callbackHandler;
|
||||||
private boolean debuggerEnabled = SmackConfiguration.DEBUG;
|
private SmackDebuggerFactory debuggerFactory;
|
||||||
private SocketFactory socketFactory;
|
private SocketFactory socketFactory;
|
||||||
private DomainBareJid xmppServiceDomain;
|
private DomainBareJid xmppServiceDomain;
|
||||||
private InetAddress hostAddress;
|
private InetAddress hostAddress;
|
||||||
|
@ -531,6 +531,9 @@ public abstract class ConnectionConfiguration {
|
||||||
private X509TrustManager customX509TrustManager;
|
private X509TrustManager customX509TrustManager;
|
||||||
|
|
||||||
protected Builder() {
|
protected Builder() {
|
||||||
|
if (SmackConfiguration.DEBUG) {
|
||||||
|
enableDefaultDebugger();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -808,15 +811,20 @@ public abstract class ConnectionConfiguration {
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public B enableDefaultDebugger() {
|
||||||
|
this.debuggerFactory = SmackConfiguration.getDefaultSmackDebuggerFactory();
|
||||||
|
assert this.debuggerFactory != null;
|
||||||
|
return getThis();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets if the new connection about to be establish is going to be debugged. By
|
* Set the Smack debugger factory used to construct Smack debuggers.
|
||||||
* default the value of {@link SmackConfiguration#DEBUG} is used.
|
|
||||||
*
|
*
|
||||||
* @param debuggerEnabled if the new connection about to be establish is going to be debugged.
|
* @param debuggerFactory the Smack debugger factory.
|
||||||
* @return a reference to this builder.
|
* @return a reference to this builder.
|
||||||
*/
|
*/
|
||||||
public B setDebuggerEnabled(boolean debuggerEnabled) {
|
public B setDebuggerFactory(SmackDebuggerFactory debuggerFactory) {
|
||||||
this.debuggerEnabled = debuggerEnabled;
|
this.debuggerFactory = debuggerFactory;
|
||||||
return getThis();
|
return getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -965,4 +973,5 @@ public abstract class ConnectionConfiguration {
|
||||||
|
|
||||||
protected abstract B getThis();
|
protected abstract B getThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
package org.jivesoftware.smack;
|
package org.jivesoftware.smack;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -30,7 +28,6 @@ import javax.net.ssl.HostnameVerifier;
|
||||||
|
|
||||||
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
|
||||||
import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory;
|
import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
|
||||||
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
|
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
|
||||||
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||||
|
@ -63,8 +60,6 @@ public final class SmackConfiguration {
|
||||||
|
|
||||||
static boolean smackInitialized = false;
|
static boolean smackInitialized = false;
|
||||||
|
|
||||||
private static SmackDebuggerFactory debuggerFactory = new ReflectionDebuggerFactory();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value that indicates whether debugging is enabled. When enabled, a debug
|
* Value that indicates whether debugging is enabled. When enabled, a debug
|
||||||
* window will apear for each new connection that will contain the following
|
* window will apear for each new connection that will contain the following
|
||||||
|
@ -80,6 +75,8 @@ public final class SmackConfiguration {
|
||||||
*/
|
*/
|
||||||
public static boolean DEBUG = false;
|
public static boolean DEBUG = false;
|
||||||
|
|
||||||
|
private static SmackDebuggerFactory DEFAULT_DEBUGGER_FACTORY = ReflectionDebuggerFactory.INSTANCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
|
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
|
||||||
* throw an exception and therefore disconnect the active connection.
|
* throw an exception and therefore disconnect the active connection.
|
||||||
|
@ -148,6 +145,14 @@ public final class SmackConfiguration {
|
||||||
defaultPacketReplyTimeout = timeout;
|
defaultPacketReplyTimeout = timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setDefaultSmackDebuggerFactory(SmackDebuggerFactory debuggerFactory) {
|
||||||
|
DEFAULT_DEBUGGER_FACTORY = Objects.requireNonNull(debuggerFactory, "Debugger factory must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SmackDebuggerFactory getDefaultSmackDebuggerFactory() {
|
||||||
|
return DEFAULT_DEBUGGER_FACTORY;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default max size of a stanza(/packet) collector before it will delete
|
* Gets the default max size of a stanza(/packet) collector before it will delete
|
||||||
* the older packets.
|
* the older packets.
|
||||||
|
@ -190,43 +195,6 @@ public final class SmackConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets Smack debugger factory.
|
|
||||||
*
|
|
||||||
* @param debuggerFactory new debugger factory implementation to be used by Smack
|
|
||||||
*/
|
|
||||||
public static void setDebuggerFactory(SmackDebuggerFactory debuggerFactory) {
|
|
||||||
SmackConfiguration.debuggerFactory = debuggerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the debugger factory.
|
|
||||||
*
|
|
||||||
* @return a debugger factory or <code>null</code>
|
|
||||||
*/
|
|
||||||
public static SmackDebuggerFactory getDebuggerFactory() {
|
|
||||||
return debuggerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new debugger instance with given arguments as parameters. May
|
|
||||||
* return <code>null</code> if no DebuggerFactory is set or if the factory
|
|
||||||
* did not produce a debugger.
|
|
||||||
*
|
|
||||||
* @param connection
|
|
||||||
* @param writer
|
|
||||||
* @param reader
|
|
||||||
* @return a new debugger or <code>null</code>
|
|
||||||
*/
|
|
||||||
public static SmackDebugger createDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
|
||||||
SmackDebuggerFactory factory = getDebuggerFactory();
|
|
||||||
if (factory == null) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return factory.create(connection, writer, reader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a SASL mechanism from the list to be used.
|
* Remove a SASL mechanism from the list to be used.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,9 +20,8 @@ import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionListener;
|
import org.jivesoftware.smack.ConnectionListener;
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||||
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.jivesoftware.smack.util.ReaderListener;
|
import org.jivesoftware.smack.util.ReaderListener;
|
||||||
|
@ -30,13 +29,10 @@ import org.jivesoftware.smack.util.WriterListener;
|
||||||
|
|
||||||
import org.jxmpp.jid.EntityFullJid;
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
|
||||||
public abstract class AbstractDebugger implements SmackDebugger {
|
public abstract class AbstractDebugger extends SmackDebugger {
|
||||||
|
|
||||||
public static boolean printInterpreted = false;
|
public static boolean printInterpreted = false;
|
||||||
|
|
||||||
private final XMPPConnection connection;
|
|
||||||
|
|
||||||
private final StanzaListener listener;
|
|
||||||
private final ConnectionListener connListener;
|
private final ConnectionListener connListener;
|
||||||
private final ReaderListener readerListener;
|
private final ReaderListener readerListener;
|
||||||
private final WriterListener writerListener;
|
private final WriterListener writerListener;
|
||||||
|
@ -44,8 +40,8 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
private ObservableWriter writer;
|
private ObservableWriter writer;
|
||||||
private ObservableReader reader;
|
private ObservableReader reader;
|
||||||
|
|
||||||
public AbstractDebugger(final XMPPConnection connection, Writer writer, Reader reader) {
|
public AbstractDebugger(final XMPPConnection connection) {
|
||||||
this.connection = connection;
|
super(connection);
|
||||||
|
|
||||||
// Create a special Reader that wraps the main Reader and logs data to the GUI.
|
// Create a special Reader that wraps the main Reader and logs data to the GUI.
|
||||||
this.reader = new ObservableReader(reader);
|
this.reader = new ObservableReader(reader);
|
||||||
|
@ -67,18 +63,6 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
};
|
};
|
||||||
this.writer.addWriterListener(writerListener);
|
this.writer.addWriterListener(writerListener);
|
||||||
|
|
||||||
// Create a thread that will listen for all incoming packets and write them to
|
|
||||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
|
||||||
// data as Smack sees it and not as it's coming in as raw XML.
|
|
||||||
listener = new StanzaListener() {
|
|
||||||
@Override
|
|
||||||
public void processStanza(Stanza packet) {
|
|
||||||
if (printInterpreted) {
|
|
||||||
log("RCV PKT (" + connection.getConnectionCounter() + "): " + packet.toXML());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
connListener = new ConnectionListener() {
|
connListener = new ConnectionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void connected(XMPPConnection connection) {
|
public void connected(XMPPConnection connection) {
|
||||||
|
@ -173,22 +157,15 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getReader() {
|
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return reader;
|
if (printInterpreted) {
|
||||||
|
log("RCV PKT (" + connection.getConnectionCounter() + "): " + streamElement.toXML());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer getWriter() {
|
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return writer;
|
// Does nothing (yet).
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getReaderListener() {
|
|
||||||
return listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getWriterListener() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,7 @@
|
||||||
package org.jivesoftware.smack.debugger;
|
package org.jivesoftware.smack.debugger;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
@ -39,8 +37,8 @@ import org.jivesoftware.smack.XMPPConnection;
|
||||||
public class ConsoleDebugger extends AbstractDebugger {
|
public class ConsoleDebugger extends AbstractDebugger {
|
||||||
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss");
|
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss");
|
||||||
|
|
||||||
public ConsoleDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
public ConsoleDebugger(XMPPConnection connection) {
|
||||||
super(connection, writer, reader);
|
super(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -64,4 +62,17 @@ public class ConsoleDebugger extends AbstractDebugger {
|
||||||
log(logMessage + sw);
|
log(logMessage + sw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class Factory implements SmackDebuggerFactory {
|
||||||
|
|
||||||
|
public static final SmackDebuggerFactory INSTANCE = new Factory();
|
||||||
|
|
||||||
|
private Factory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
|
||||||
|
return new ConsoleDebugger(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2014 Florian Schmaus
|
* Copyright 2014-2017 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.
|
||||||
|
@ -16,8 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack.debugger;
|
package org.jivesoftware.smack.debugger;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -38,8 +36,8 @@ public class JulDebugger extends AbstractDebugger {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(JulDebugger.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(JulDebugger.class.getName());
|
||||||
|
|
||||||
public JulDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
public JulDebugger(XMPPConnection connection) {
|
||||||
super(connection, writer, reader);
|
super(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2014 Vyacheslav Blinov
|
* Copyright 2014 Vyacheslav Blinov, 2017 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.
|
||||||
|
@ -14,12 +14,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.jivesoftware.smack.debugger;
|
package org.jivesoftware.smack.debugger;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -27,10 +23,15 @@ import java.util.logging.Logger;
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
|
||||||
public class ReflectionDebuggerFactory implements SmackDebuggerFactory {
|
public final class ReflectionDebuggerFactory implements SmackDebuggerFactory {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ReflectionDebuggerFactory.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ReflectionDebuggerFactory.class.getName());
|
||||||
private static final String DEBUGGER_CLASS_PROPERTY_NAME = "smack.debuggerClass";
|
private static final String DEBUGGER_CLASS_PROPERTY_NAME = "smack.debuggerClass";
|
||||||
|
|
||||||
|
public static final ReflectionDebuggerFactory INSTANCE = new ReflectionDebuggerFactory();
|
||||||
|
|
||||||
|
private ReflectionDebuggerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible default debugger implementations. The order of enumeration is the one in which we try
|
* Possible default debugger implementations. The order of enumeration is the one in which we try
|
||||||
* to instantiate these.
|
* to instantiate these.
|
||||||
|
@ -76,14 +77,14 @@ public class ReflectionDebuggerFactory implements SmackDebuggerFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmackDebugger create(XMPPConnection connection, Writer writer, Reader reader) throws IllegalArgumentException {
|
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
|
||||||
Class<SmackDebugger> debuggerClass = getDebuggerClass();
|
Class<SmackDebugger> debuggerClass = getDebuggerClass();
|
||||||
if (debuggerClass != null) {
|
if (debuggerClass != null) {
|
||||||
// Create a new debugger instance using 3arg constructor
|
// Create a new debugger instance using 3arg constructor
|
||||||
try {
|
try {
|
||||||
Constructor<SmackDebugger> constructor = debuggerClass
|
Constructor<SmackDebugger> constructor = debuggerClass
|
||||||
.getConstructor(XMPPConnection.class, Writer.class, Reader.class);
|
.getConstructor(XMPPConnection.class);
|
||||||
return constructor.newInstance(connection, writer, reader);
|
return constructor.newInstance(connection);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IllegalArgumentException("Can't initialize the configured debugger!", e);
|
throw new IllegalArgumentException("Can't initialize the configured debugger!", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software.
|
* Copyright 2003-2007 Jive Software, 2017 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.
|
||||||
|
@ -20,7 +20,8 @@ package org.jivesoftware.smack.debugger;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||||
|
|
||||||
import org.jxmpp.jid.EntityFullJid;
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
|
||||||
|
@ -33,7 +34,13 @@ import org.jxmpp.jid.EntityFullJid;
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public interface SmackDebugger {
|
public abstract class SmackDebugger {
|
||||||
|
|
||||||
|
protected final XMPPConnection connection;
|
||||||
|
|
||||||
|
protected SmackDebugger(XMPPConnection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a user has logged in to the server. The user could be an anonymous user, this
|
* Called when a user has logged in to the server. The user could be an anonymous user, this
|
||||||
|
@ -42,22 +49,9 @@ 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
|
||||||
*/
|
*/
|
||||||
|
// TODO: Should be replaced with a connection listener authenticed().
|
||||||
public abstract void userHasLogged(EntityFullJid user);
|
public abstract void userHasLogged(EntityFullJid user);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the special Reader that wraps the main Reader and logs data to the GUI.
|
|
||||||
*
|
|
||||||
* @return the special Reader that wraps the main Reader and logs data to the GUI.
|
|
||||||
*/
|
|
||||||
public abstract Reader getReader();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the special Writer that wraps the main Writer and logs data to the GUI.
|
|
||||||
*
|
|
||||||
* @return the special Writer that wraps the main Writer and logs data to the GUI.
|
|
||||||
*/
|
|
||||||
public abstract Writer getWriter();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new special Reader that wraps the new connection Reader. The connection
|
* Returns a new special Reader that wraps the new connection Reader. The connection
|
||||||
* has been secured so the connection is using a new reader and writer. The debugger
|
* has been secured so the connection is using a new reader and writer. The debugger
|
||||||
|
@ -79,20 +73,23 @@ public interface SmackDebugger {
|
||||||
public abstract Writer newConnectionWriter(Writer writer);
|
public abstract Writer newConnectionWriter(Writer writer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the thread that will listen for all incoming packets and write them to the GUI.
|
* Used by the connection to notify about an incoming top level stream element.
|
||||||
* This is what we call "interpreted" stanza(/packet) data, since it's the stanza(/packet) data as Smack sees
|
* <p>
|
||||||
* it and not as it's coming in as raw XML.
|
* This method is invoked right after the incoming stream was parsed.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @return the PacketListener that will listen for all incoming packets and write them to
|
* @param streamElement the incoming top level stream element.
|
||||||
* the GUI
|
|
||||||
*/
|
*/
|
||||||
public abstract StanzaListener getReaderListener();
|
public abstract void onIncomingStreamElement(TopLevelStreamElement streamElement);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the thread that will listen for all outgoing packets and write them to the GUI.
|
* Used by the connection to notify about a outgoing top level stream element.
|
||||||
|
* <p>
|
||||||
|
* This method is invoked right before the element is serialized to XML and put into the outgoing stream.
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @return the PacketListener that will listen for all sent packets and write them to
|
* @param streamElement the outgoing top level stream element.
|
||||||
* the GUI
|
|
||||||
*/
|
*/
|
||||||
public abstract StanzaListener getWriterListener();
|
public abstract void onOutgoingStreamElement(TopLevelStreamElement streamElement);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2014 Vyacheslav Blinov
|
* Copyright 2014 Vyacheslav Blinov, 2017 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.
|
||||||
|
@ -14,20 +14,16 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
package org.jivesoftware.smack.debugger;
|
package org.jivesoftware.smack.debugger;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
|
||||||
public interface SmackDebuggerFactory {
|
public interface SmackDebuggerFactory {
|
||||||
/**
|
/**
|
||||||
* Initialize the new SmackDebugger instance.
|
* Initialize the new SmackDebugger instance.
|
||||||
*
|
*
|
||||||
|
* @param connection the XMPP connection this debugger is going to get attached to.
|
||||||
* @throws IllegalArgumentException if the SmackDebugger can't be loaded.
|
* @throws IllegalArgumentException if the SmackDebugger can't be loaded.
|
||||||
*/
|
*/
|
||||||
SmackDebugger create(XMPPConnection connection, Writer writer, Reader reader) throws IllegalArgumentException;
|
SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2015 Florian Schmaus.
|
* Copyright 2015-2017 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.
|
||||||
|
@ -46,6 +46,9 @@ public class StandardExtensionElementParserTest {
|
||||||
assertEquals("attr2-value", barNs2Element.getAttributeValue("attr2"));
|
assertEquals("attr2-value", barNs2Element.getAttributeValue("attr2"));
|
||||||
|
|
||||||
assertEquals("another-element-text", parsedElement.getFirstElement("another-element").getText());
|
assertEquals("another-element-text", parsedElement.getFirstElement("another-element").getText());
|
||||||
|
|
||||||
|
String parsedElementString = parsedElement.toXML().toString();
|
||||||
|
assertEquals(elementString, parsedElementString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
|
|
||||||
package org.jivesoftware.smackx.debugger.slf4j;
|
package org.jivesoftware.smackx.debugger.slf4j;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
|
@ -27,9 +24,15 @@ import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
/**
|
/**
|
||||||
* Implementation of SmackDebuggerFactory which always creates instance of SLF4JSmackDebugger.
|
* Implementation of SmackDebuggerFactory which always creates instance of SLF4JSmackDebugger.
|
||||||
*/
|
*/
|
||||||
public class SLF4JDebuggerFactory implements SmackDebuggerFactory {
|
public final class SLF4JDebuggerFactory implements SmackDebuggerFactory {
|
||||||
|
|
||||||
|
public static final SLF4JDebuggerFactory INSTANCE = new SLF4JDebuggerFactory();
|
||||||
|
|
||||||
|
private SLF4JDebuggerFactory() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SmackDebugger create(XMPPConnection connection, Writer writer, Reader reader) throws IllegalArgumentException {
|
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
|
||||||
return new SLF4JSmackDebugger(connection, writer, reader);
|
return new SLF4JSmackDebugger(connection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2014 Vyacheslav Blinov
|
|
||||||
*
|
|
||||||
* 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.smackx.debugger.slf4j;
|
|
||||||
|
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
class SLF4JLoggingPacketListener implements StanzaListener {
|
|
||||||
private final Logger logger;
|
|
||||||
private final String prefix;
|
|
||||||
|
|
||||||
public SLF4JLoggingPacketListener(Logger logger, String prefix) {
|
|
||||||
this.logger = Validate.notNull(logger);
|
|
||||||
this.prefix = Validate.notNull(prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processStanza(Stanza packet) {
|
|
||||||
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
|
|
||||||
logger.debug("{}: PKT [{}] '{}'", prefix, packet.getClass().getName(), packet.toXML());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -22,9 +22,9 @@ import java.io.Writer;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackConfiguration;
|
import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||||
|
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||||
import org.jivesoftware.smack.util.ObservableReader;
|
import org.jivesoftware.smack.util.ObservableReader;
|
||||||
import org.jivesoftware.smack.util.ObservableWriter;
|
import org.jivesoftware.smack.util.ObservableWriter;
|
||||||
|
|
||||||
|
@ -38,7 +38,8 @@ import org.slf4j.LoggerFactory;
|
||||||
* Use in conjunction with your SLF4J bindings of choice.
|
* Use in conjunction with your SLF4J bindings of choice.
|
||||||
* See SLF4J manual for more details about bindings usage.
|
* See SLF4J manual for more details about bindings usage.
|
||||||
*/
|
*/
|
||||||
public class SLF4JSmackDebugger implements SmackDebugger {
|
public class SLF4JSmackDebugger extends SmackDebugger {
|
||||||
|
|
||||||
public static final String LOGGER_NAME = "SMACK";
|
public static final String LOGGER_NAME = "SMACK";
|
||||||
private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
|
private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
|
||||||
public static final AtomicBoolean printInterpreted = new AtomicBoolean(true);
|
public static final AtomicBoolean printInterpreted = new AtomicBoolean(true);
|
||||||
|
@ -46,10 +47,6 @@ public class SLF4JSmackDebugger implements SmackDebugger {
|
||||||
public static final String SENT_TAG = "SENT";
|
public static final String SENT_TAG = "SENT";
|
||||||
public static final String RECEIVED_TAG = "RECV";
|
public static final String RECEIVED_TAG = "RECV";
|
||||||
|
|
||||||
private final XMPPConnection connection;
|
|
||||||
|
|
||||||
private final StanzaListener receivedListener = new SLF4JLoggingPacketListener(logger, RECEIVED_TAG);
|
|
||||||
private final StanzaListener sentListener = new SLF4JLoggingPacketListener(logger, SENT_TAG);
|
|
||||||
private final SLF4JRawXmlListener slf4JRawXmlListener = new SLF4JRawXmlListener(logger);
|
private final SLF4JRawXmlListener slf4JRawXmlListener = new SLF4JRawXmlListener(logger);
|
||||||
|
|
||||||
private ObservableWriter writer;
|
private ObservableWriter writer;
|
||||||
|
@ -59,17 +56,16 @@ public class SLF4JSmackDebugger implements SmackDebugger {
|
||||||
* Makes Smack use this Debugger.
|
* Makes Smack use this Debugger.
|
||||||
*/
|
*/
|
||||||
public static void enable() {
|
public static void enable() {
|
||||||
SmackConfiguration.setDebuggerFactory(new SLF4JDebuggerFactory());
|
SmackConfiguration.DEBUG = true;
|
||||||
|
SmackConfiguration.setDefaultSmackDebuggerFactory(SLF4JDebuggerFactory.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new SLF4J Smack Debugger instance.
|
* Create new SLF4J Smack Debugger instance.
|
||||||
* @param connection Smack connection to debug
|
* @param connection Smack connection to debug
|
||||||
* @param writer connection data writer to observe
|
|
||||||
* @param reader connection data reader to observe
|
|
||||||
*/
|
*/
|
||||||
public SLF4JSmackDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
SLF4JSmackDebugger(XMPPConnection connection) {
|
||||||
this.connection = connection;
|
super(connection);
|
||||||
this.writer = new ObservableWriter(writer);
|
this.writer = new ObservableWriter(writer);
|
||||||
this.writer.addWriterListener(slf4JRawXmlListener);
|
this.writer.addWriterListener(slf4JRawXmlListener);
|
||||||
this.reader = new ObservableReader(Validate.notNull(reader));
|
this.reader = new ObservableReader(Validate.notNull(reader));
|
||||||
|
@ -101,22 +97,17 @@ public class SLF4JSmackDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getReader() {
|
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return reader;
|
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
|
||||||
|
logger.debug("IN {}: {}", streamElement.getClass().getName(), streamElement.toXML());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer getWriter() {
|
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return writer;
|
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
|
||||||
|
logger.debug("OUT {}: {}", streamElement.getClass().getName(), streamElement.toXML());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getReaderListener() {
|
|
||||||
return receivedListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getWriterListener() {
|
|
||||||
return sentListener;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,13 +72,14 @@ import javax.xml.transform.stream.StreamSource;
|
||||||
import org.jivesoftware.smack.AbstractConnectionListener;
|
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
import org.jivesoftware.smack.ConnectionListener;
|
import org.jivesoftware.smack.ConnectionListener;
|
||||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||||
|
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.Presence;
|
import org.jivesoftware.smack.packet.Presence;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||||
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.jivesoftware.smack.util.ReaderListener;
|
import org.jivesoftware.smack.util.ReaderListener;
|
||||||
|
@ -97,7 +98,7 @@ import org.jxmpp.jid.Jid;
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class EnhancedDebugger implements SmackDebugger {
|
public class EnhancedDebugger extends SmackDebugger {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(EnhancedDebugger.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(EnhancedDebugger.class.getName());
|
||||||
|
|
||||||
|
@ -149,10 +150,6 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
private JFormattedTextField userField = null;
|
private JFormattedTextField userField = null;
|
||||||
private JFormattedTextField statusField = null;
|
private JFormattedTextField statusField = null;
|
||||||
|
|
||||||
private XMPPConnection connection = null;
|
|
||||||
|
|
||||||
private StanzaListener packetReaderListener = null;
|
|
||||||
private StanzaListener packetWriterListener = null;
|
|
||||||
private ConnectionListener connListener = null;
|
private ConnectionListener connListener = null;
|
||||||
|
|
||||||
private Writer writer;
|
private Writer writer;
|
||||||
|
@ -177,18 +174,9 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
JTabbedPane tabbedPane;
|
JTabbedPane tabbedPane;
|
||||||
|
|
||||||
public EnhancedDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
public EnhancedDebugger(XMPPConnection connection) {
|
||||||
this.connection = connection;
|
super(connection);
|
||||||
this.writer = writer;
|
|
||||||
this.reader = reader;
|
|
||||||
createDebug();
|
|
||||||
EnhancedDebuggerWindow.addDebugger(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the debug process, which is a GUI window that displays XML traffic.
|
|
||||||
*/
|
|
||||||
private void createDebug() {
|
|
||||||
// We'll arrange the UI into six tabs. The first tab contains all data, the second
|
// We'll arrange the UI into six tabs. The first tab contains all data, the second
|
||||||
// client generated XML, the third server generated XML, the fourth allows to send
|
// client generated XML, the third server generated XML, the fourth allows to send
|
||||||
// ad-hoc messages and the fifth contains connection information.
|
// ad-hoc messages and the fifth contains connection information.
|
||||||
|
@ -203,41 +191,6 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
// Add the connection information panel
|
// Add the connection information panel
|
||||||
addInformationPanel();
|
addInformationPanel();
|
||||||
|
|
||||||
// Create a thread that will listen for all incoming packets and write them to
|
|
||||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
|
||||||
// data as Smack sees it and not as it's coming in as raw XML.
|
|
||||||
packetReaderListener = new StanzaListener() {
|
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processStanza(final Stanza packet) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
addReadPacketToTable(dateFormatter, packet);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a thread that will listen for all outgoing packets and write them to
|
|
||||||
// the GUI.
|
|
||||||
packetWriterListener = new StanzaListener() {
|
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processStanza(final Stanza packet) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
addSentPacketToTable(dateFormatter, packet);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create a thread that will listen for any connection closed event
|
// Create a thread that will listen for any connection closed event
|
||||||
connListener = new AbstractConnectionListener() {
|
connListener = new AbstractConnectionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -294,6 +247,8 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnhancedDebuggerWindow.addDebugger(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBasicPanels() {
|
private void addBasicPanels() {
|
||||||
|
@ -793,26 +748,6 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Reader getReader() {
|
|
||||||
return reader;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Writer getWriter() {
|
|
||||||
return writer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getReaderListener() {
|
|
||||||
return packetReaderListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getWriterListener() {
|
|
||||||
return packetWriterListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the statistics table
|
* Updates the statistics table
|
||||||
*/
|
*/
|
||||||
|
@ -839,12 +774,21 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
||||||
* @param packet the read stanza(/packet) to add to the table
|
* @param packet the read stanza(/packet) to add to the table
|
||||||
*/
|
*/
|
||||||
private void addReadPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
private void addReadPacketToTable(final SimpleDateFormat dateFormatter, final TopLevelStreamElement packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String messageType;
|
String messageType;
|
||||||
Jid from = packet.getFrom();
|
Jid from;
|
||||||
|
String stanzaId;
|
||||||
|
if (packet instanceof Stanza) {
|
||||||
|
Stanza stanza = (Stanza) packet;
|
||||||
|
from = stanza.getFrom();
|
||||||
|
stanzaId = stanza.getStanzaId();
|
||||||
|
} else {
|
||||||
|
from = null;
|
||||||
|
stanzaId = "(Nonza)";
|
||||||
|
}
|
||||||
String type = "";
|
String type = "";
|
||||||
Icon packetTypeIcon;
|
Icon packetTypeIcon;
|
||||||
receivedPackets++;
|
receivedPackets++;
|
||||||
|
@ -885,7 +829,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
packetReceivedIcon,
|
packetReceivedIcon,
|
||||||
packetTypeIcon,
|
packetTypeIcon,
|
||||||
messageType,
|
messageType,
|
||||||
packet.getStanzaId(),
|
stanzaId,
|
||||||
type,
|
type,
|
||||||
"",
|
"",
|
||||||
from});
|
from});
|
||||||
|
@ -901,12 +845,21 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
* @param dateFormatter the SimpleDateFormat to use to format Dates
|
||||||
* @param packet the sent stanza(/packet) to add to the table
|
* @param packet the sent stanza(/packet) to add to the table
|
||||||
*/
|
*/
|
||||||
private void addSentPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
private void addSentPacketToTable(final SimpleDateFormat dateFormatter, final TopLevelStreamElement packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String messageType;
|
String messageType;
|
||||||
Jid to = packet.getTo();
|
Jid to;
|
||||||
|
String stanzaId;
|
||||||
|
if (packet instanceof Stanza) {
|
||||||
|
Stanza stanza = (Stanza) packet;
|
||||||
|
to = stanza.getTo();
|
||||||
|
stanzaId = stanza.getStanzaId();
|
||||||
|
} else {
|
||||||
|
to = null;
|
||||||
|
stanzaId = "(Nonza)";
|
||||||
|
}
|
||||||
String type = "";
|
String type = "";
|
||||||
Icon packetTypeIcon;
|
Icon packetTypeIcon;
|
||||||
sentPackets++;
|
sentPackets++;
|
||||||
|
@ -947,7 +900,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
packetSentIcon,
|
packetSentIcon,
|
||||||
packetTypeIcon,
|
packetTypeIcon,
|
||||||
messageType,
|
messageType,
|
||||||
packet.getStanzaId(),
|
stanzaId,
|
||||||
type,
|
type,
|
||||||
to,
|
to,
|
||||||
""});
|
""});
|
||||||
|
@ -1006,8 +959,6 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
*/
|
*/
|
||||||
void cancel() {
|
void cancel() {
|
||||||
connection.removeConnectionListener(connListener);
|
connection.removeConnectionListener(connListener);
|
||||||
connection.removeAsyncStanzaListener(packetReaderListener);
|
|
||||||
connection.removePacketSendingListener(packetWriterListener);
|
|
||||||
((ObservableReader) reader).removeReaderListener(readerListener);
|
((ObservableReader) reader).removeReaderListener(readerListener);
|
||||||
((ObservableWriter) writer).removeWriterListener(writerListener);
|
((ObservableWriter) writer).removeWriterListener(writerListener);
|
||||||
messagesTable = null;
|
messagesTable = null;
|
||||||
|
@ -1099,4 +1050,40 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onIncomingStreamElement(final TopLevelStreamElement streamElement) {
|
||||||
|
final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
addReadPacketToTable(dateFormatter, streamElement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOutgoingStreamElement(final TopLevelStreamElement streamElement) {
|
||||||
|
final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
addSentPacketToTable(dateFormatter, streamElement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Factory implements SmackDebuggerFactory {
|
||||||
|
|
||||||
|
public static final SmackDebuggerFactory INSTANCE = new Factory();
|
||||||
|
|
||||||
|
private Factory() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
|
||||||
|
return new EnhancedDebugger(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
*
|
*
|
||||||
* @return the unique EnhancedDebuggerWindow instance
|
* @return the unique EnhancedDebuggerWindow instance
|
||||||
*/
|
*/
|
||||||
public static EnhancedDebuggerWindow getInstance() {
|
public synchronized static EnhancedDebuggerWindow getInstance() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new EnhancedDebuggerWindow();
|
instance = new EnhancedDebuggerWindow();
|
||||||
}
|
}
|
||||||
|
@ -345,7 +345,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
*
|
*
|
||||||
* @param evt the event that indicates that the root window is closing
|
* @param evt the event that indicates that the root window is closing
|
||||||
*/
|
*/
|
||||||
public void rootWindowClosing(WindowEvent evt) {
|
private synchronized void rootWindowClosing(WindowEvent evt) {
|
||||||
// Notify to all the debuggers to stop debugging
|
// Notify to all the debuggers to stop debugging
|
||||||
for (EnhancedDebugger debugger : debuggers) {
|
for (EnhancedDebugger debugger : debuggers) {
|
||||||
debugger.cancel();
|
debugger.cancel();
|
||||||
|
@ -354,6 +354,8 @@ public final class EnhancedDebuggerWindow {
|
||||||
debuggers.clear();
|
debuggers.clear();
|
||||||
// Release the default instance
|
// Release the default instance
|
||||||
instance = null;
|
instance = null;
|
||||||
|
frame = null;
|
||||||
|
notifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -393,4 +395,14 @@ public final class EnhancedDebuggerWindow {
|
||||||
public boolean isVisible() {
|
public boolean isVisible() {
|
||||||
return frame != null && frame.isVisible();
|
return frame != null && frame.isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void waitUntilClosed() throws InterruptedException {
|
||||||
|
if (frame == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (frame != null) {
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,9 @@ import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
import javax.swing.JTextArea;
|
import javax.swing.JTextArea;
|
||||||
|
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.debugger.SmackDebugger;
|
import org.jivesoftware.smack.debugger.SmackDebugger;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||||
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.jivesoftware.smack.util.ReaderListener;
|
import org.jivesoftware.smack.util.ReaderListener;
|
||||||
|
@ -57,24 +56,22 @@ import org.jxmpp.jid.EntityFullJid;
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class LiteDebugger implements SmackDebugger {
|
public class LiteDebugger extends SmackDebugger {
|
||||||
|
|
||||||
private static final String NEWLINE = "\n";
|
private static final String NEWLINE = "\n";
|
||||||
|
|
||||||
private JFrame frame = null;
|
private final JTextArea interpretedText1 = new JTextArea();
|
||||||
private XMPPConnection connection = null;
|
private final JTextArea interpretedText2 = new JTextArea();
|
||||||
|
|
||||||
private StanzaListener listener = null;
|
private JFrame frame = null;
|
||||||
|
|
||||||
private Writer writer;
|
private Writer writer;
|
||||||
private Reader reader;
|
private Reader reader;
|
||||||
private ReaderListener readerListener;
|
private ReaderListener readerListener;
|
||||||
private WriterListener writerListener;
|
private WriterListener writerListener;
|
||||||
|
|
||||||
public LiteDebugger(XMPPConnection connection, Writer writer, Reader reader) {
|
public LiteDebugger(XMPPConnection connection) {
|
||||||
this.connection = connection;
|
super(connection);
|
||||||
this.writer = writer;
|
|
||||||
this.reader = reader;
|
|
||||||
createDebug();
|
createDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +178,6 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
menu.add(menuItem2);
|
menu.add(menuItem2);
|
||||||
|
|
||||||
// Create UI elements for interpreted XML traffic.
|
// Create UI elements for interpreted XML traffic.
|
||||||
final JTextArea interpretedText1 = new JTextArea();
|
|
||||||
final JTextArea interpretedText2 = new JTextArea();
|
|
||||||
interpretedText1.setEditable(false);
|
interpretedText1.setEditable(false);
|
||||||
interpretedText2.setEditable(false);
|
interpretedText2.setEditable(false);
|
||||||
interpretedText1.setForeground(new Color(1, 94, 35));
|
interpretedText1.setForeground(new Color(1, 94, 35));
|
||||||
|
@ -267,19 +262,6 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
// and writer will use the debug versions when they are created.
|
// and writer will use the debug versions when they are created.
|
||||||
reader = debugReader;
|
reader = debugReader;
|
||||||
writer = debugWriter;
|
writer = debugWriter;
|
||||||
|
|
||||||
// Create a thread that will listen for all incoming packets and write them to
|
|
||||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
|
||||||
// data as Smack sees it and not as it's coming in as raw XML.
|
|
||||||
listener = new StanzaListener() {
|
|
||||||
@Override
|
|
||||||
public void processStanza(Stanza packet) {
|
|
||||||
interpretedText1.append(packet.toXML().toString());
|
|
||||||
interpretedText2.append(packet.toXML().toString());
|
|
||||||
interpretedText1.append(NEWLINE);
|
|
||||||
interpretedText2.append(NEWLINE);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,7 +271,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
* @param evt the event that indicates that the root window is closing
|
* @param evt the event that indicates that the root window is closing
|
||||||
*/
|
*/
|
||||||
public void rootWindowClosing(WindowEvent evt) {
|
public void rootWindowClosing(WindowEvent evt) {
|
||||||
connection.removeAsyncStanzaListener(listener);
|
// TODO: Remove debugger from connection.
|
||||||
((ObservableReader) reader).removeReaderListener(readerListener);
|
((ObservableReader) reader).removeReaderListener(readerListener);
|
||||||
((ObservableWriter) writer).removeWriterListener(writerListener);
|
((ObservableWriter) writer).removeWriterListener(writerListener);
|
||||||
}
|
}
|
||||||
|
@ -348,22 +330,16 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Reader getReader() {
|
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return reader;
|
interpretedText1.append(streamElement.toXML().toString());
|
||||||
|
interpretedText2.append(streamElement.toXML().toString());
|
||||||
|
interpretedText1.append(NEWLINE);
|
||||||
|
interpretedText2.append(NEWLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer getWriter() {
|
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
|
||||||
return writer;
|
// Does nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getReaderListener() {
|
|
||||||
return listener;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StanzaListener getWriterListener() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,13 @@ package org.jivesoftware.smackx.jft.adapter;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.NamedElement;
|
||||||
import org.jivesoftware.smackx.jft.component.JingleFileTransfer;
|
import org.jivesoftware.smackx.jft.component.JingleFileTransfer;
|
||||||
import org.jivesoftware.smackx.jft.component.JingleIncomingFileOffer;
|
import org.jivesoftware.smackx.jft.component.JingleIncomingFileOffer;
|
||||||
import org.jivesoftware.smackx.jft.component.JingleIncomingFileRequest;
|
import org.jivesoftware.smackx.jft.component.JingleIncomingFileRequest;
|
||||||
import org.jivesoftware.smackx.jft.element.JingleFileTransferChildElement;
|
import org.jivesoftware.smackx.jft.element.JingleFileTransferChildElement;
|
||||||
import org.jivesoftware.smackx.jft.element.JingleFileTransferElement;
|
import org.jivesoftware.smackx.jft.element.JingleFileTransferElement;
|
||||||
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
import org.jivesoftware.smackx.jingle.adapter.JingleDescriptionAdapter;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionChildElement;
|
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@ public class JingleFileTransferAdapter implements JingleDescriptionAdapter<Jingl
|
||||||
public JingleFileTransfer descriptionFromElement(JingleContentElement.Creator creator, JingleContentElement.Senders senders,
|
public JingleFileTransfer descriptionFromElement(JingleContentElement.Creator creator, JingleContentElement.Senders senders,
|
||||||
String contentName, String contentDisposition, JingleContentDescriptionElement element) {
|
String contentName, String contentDisposition, JingleContentDescriptionElement element) {
|
||||||
JingleFileTransferElement description = (JingleFileTransferElement) element;
|
JingleFileTransferElement description = (JingleFileTransferElement) element;
|
||||||
List<JingleContentDescriptionChildElement> childs = description.getJingleContentDescriptionChildren();
|
List<NamedElement> children = description.getJingleContentDescriptionChildren();
|
||||||
assert childs.size() == 1;
|
assert children.size() == 1;
|
||||||
JingleFileTransferChildElement file = (JingleFileTransferChildElement) childs.get(0);
|
JingleFileTransferChildElement file = (JingleFileTransferChildElement) children.get(0);
|
||||||
|
|
||||||
if (senders == JingleContentElement.Senders.initiator) {
|
if (senders == JingleContentElement.Senders.initiator) {
|
||||||
return new JingleIncomingFileOffer(file);
|
return new JingleIncomingFileOffer(file);
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
|
import org.jivesoftware.smack.packet.NamedElement;
|
||||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,9 +38,9 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
|
||||||
|
|
||||||
public static final String ELEMENT = "description";
|
public static final String ELEMENT = "description";
|
||||||
|
|
||||||
private final List<JingleContentDescriptionChildElement> payloads;
|
private final List<NamedElement> payloads;
|
||||||
|
|
||||||
protected JingleContentDescriptionElement(List<JingleContentDescriptionChildElement> payloads) {
|
protected JingleContentDescriptionElement(List<? extends NamedElement> payloads) {
|
||||||
if (payloads != null) {
|
if (payloads != null) {
|
||||||
this.payloads = Collections.unmodifiableList(payloads);
|
this.payloads = Collections.unmodifiableList(payloads);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JingleContentDescriptionChildElement> getJingleContentDescriptionChildren() {
|
public List<NamedElement> getJingleContentDescriptionChildren() {
|
||||||
return payloads;
|
return payloads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final XmlStringBuilder toXML() {
|
public XmlStringBuilder toXML() {
|
||||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||||
addExtraAttributes(xml);
|
addExtraAttributes(xml);
|
||||||
xml.rightAngleBracket();
|
xml.rightAngleBracket();
|
||||||
|
|
|
@ -115,9 +115,8 @@ public final class JingleContentElement implements NamedElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an Iterator for the JingleTransports in the packet.
|
* Return the transport of the content.
|
||||||
*
|
* @return transport.
|
||||||
* @return an Iterator for the JingleTransports in the packet.
|
|
||||||
*/
|
*/
|
||||||
public JingleContentTransportElement getTransport() {
|
public JingleContentTransportElement getTransport() {
|
||||||
return transport;
|
return transport;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public abstract class JingleContentTransportElement implements ExtensionElement
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final XmlStringBuilder toXML() {
|
public XmlStringBuilder toXML() {
|
||||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||||
addExtraAttributes(xml);
|
addExtraAttributes(xml);
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,18 @@ public final class JingleElement extends IQ {
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JingleContentElement getSoleContentOrThrow() {
|
||||||
|
if (contents.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contents.size() == 1) {
|
||||||
|
return contents.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("More than one content is present.");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||||
xml.optAttribute(INITIATOR_ATTRIBUTE_NAME, getInitiator());
|
xml.optAttribute(INITIATOR_ATTRIBUTE_NAME, getInitiator());
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Florian Schmaus, Paul Schaub.
|
||||||
|
*
|
||||||
|
* 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.smackx.jingle.element;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.StandardExtensionElement;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
|
public final class UnknownJingleContentDescriptionElement extends JingleContentDescriptionElement {
|
||||||
|
|
||||||
|
private final StandardExtensionElement standardExtensionElement;
|
||||||
|
|
||||||
|
public UnknownJingleContentDescriptionElement(StandardExtensionElement standardExtensionElement) {
|
||||||
|
super(standardExtensionElement.getElements());
|
||||||
|
this.standardExtensionElement = standardExtensionElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return standardExtensionElement.getElementName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return standardExtensionElement.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlStringBuilder toXML() {
|
||||||
|
return standardExtensionElement.toXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardExtensionElement getStandardExtensionElement() {
|
||||||
|
return standardExtensionElement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Florian Schmaus, Paul Schaub.
|
||||||
|
*
|
||||||
|
* 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.smackx.jingle.element;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.StandardExtensionElement;
|
||||||
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
|
|
||||||
|
public final class UnknownJingleContentTransportElement extends JingleContentTransportElement {
|
||||||
|
|
||||||
|
private final StandardExtensionElement standardExtensionElement;
|
||||||
|
|
||||||
|
public UnknownJingleContentTransportElement(StandardExtensionElement standardExtensionElement) {
|
||||||
|
super(null, null);
|
||||||
|
this.standardExtensionElement = standardExtensionElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getElementName() {
|
||||||
|
return standardExtensionElement.getElementName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getNamespace() {
|
||||||
|
return standardExtensionElement.getNamespace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XmlStringBuilder toXML() {
|
||||||
|
return standardExtensionElement.toXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<JingleContentTransportCandidateElement> getCandidates() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JingleContentTransportInfoElement getInfo() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StandardExtensionElement getStandardExtensionElement() {
|
||||||
|
return standardExtensionElement;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,16 +18,19 @@ package org.jivesoftware.smackx.jingle.provider;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.StandardExtensionElement;
|
||||||
|
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider;
|
||||||
import org.jivesoftware.smack.provider.IQProvider;
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
import org.jivesoftware.smack.util.ParserUtils;
|
import org.jivesoftware.smack.util.ParserUtils;
|
||||||
import org.jivesoftware.smackx.jingle.JingleManager;
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
import org.jivesoftware.smackx.jingle.element.JingleAction;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentSecurityElement;
|
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
|
import org.jivesoftware.smackx.jingle.element.JingleReasonElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentDescriptionElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransportElement;
|
||||||
|
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
@ -122,34 +125,31 @@ public class JingleProvider extends IQProvider<JingleElement> {
|
||||||
String namespace = parser.getNamespace();
|
String namespace = parser.getNamespace();
|
||||||
switch (tagName) {
|
switch (tagName) {
|
||||||
case JingleContentDescriptionElement.ELEMENT: {
|
case JingleContentDescriptionElement.ELEMENT: {
|
||||||
|
JingleContentDescriptionElement description;
|
||||||
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
|
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
// TODO handle this case (DefaultExtensionElement wrapped in something?)
|
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
||||||
break;
|
description = new UnknownJingleContentDescriptionElement(standardExtensionElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
description = provider.parse(parser);
|
||||||
}
|
}
|
||||||
JingleContentDescriptionElement description = provider.parse(parser);
|
|
||||||
builder.setDescription(description);
|
builder.setDescription(description);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JingleContentTransportElement.ELEMENT: {
|
case JingleContentTransportElement.ELEMENT: {
|
||||||
|
JingleContentTransportElement transport;
|
||||||
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
|
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
|
||||||
if (provider == null) {
|
if (provider == null) {
|
||||||
// TODO handle this case (DefaultExtensionElement wrapped in something?)
|
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
|
||||||
break;
|
transport = new UnknownJingleContentTransportElement(standardExtensionElement);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
transport = provider.parse(parser);
|
||||||
}
|
}
|
||||||
JingleContentTransportElement transport = provider.parse(parser);
|
|
||||||
builder.setTransport(transport);
|
builder.setTransport(transport);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JingleContentSecurityElement.ELEMENT: {
|
|
||||||
JingleContentSecurityProvider<?> provider = JingleManager.getJingleSecurityProvider(namespace);
|
|
||||||
if (provider == null) {
|
|
||||||
//TODO: handle this case (see above)
|
|
||||||
}
|
|
||||||
JingleContentSecurityElement security = provider.parse(parser);
|
|
||||||
builder.setSecurity(security);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
LOGGER.severe("Unknown Jingle content element: " + tagName);
|
LOGGER.severe("Unknown Jingle content element: " + tagName);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -65,7 +65,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
|
||||||
private List<Bytestream.StreamHost> localStreamHosts = null;
|
private List<Bytestream.StreamHost> localStreamHosts = null;
|
||||||
private List<Bytestream.StreamHost> availableStreamHosts = null;
|
private List<Bytestream.StreamHost> availableStreamHosts = null;
|
||||||
|
|
||||||
private static boolean useLocalCandidates = false;
|
private static boolean useLocalCandidates = true;
|
||||||
private static boolean useExternalCandidates = true;
|
private static boolean useExternalCandidates = true;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -222,19 +222,19 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
|
||||||
}
|
}
|
||||||
|
|
||||||
JingleElement createCandidateUsed(JingleS5BTransport transport, JingleS5BTransportCandidate candidate) {
|
JingleElement createCandidateUsed(JingleS5BTransport transport, JingleS5BTransportCandidate candidate) {
|
||||||
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateUsed(candidate.getCandidateId()));
|
return createTransportInfo(transport, new JingleS5BTransportInfoElement.CandidateUsed(candidate.getCandidateId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
JingleElement createCandidateError(JingleS5BTransport transport) {
|
JingleElement createCandidateError(JingleS5BTransport transport) {
|
||||||
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateError());
|
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateError.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
JingleElement createProxyError(JingleS5BTransport transport) {
|
JingleElement createProxyError(JingleS5BTransport transport) {
|
||||||
return createTransportInfo(transport, JingleS5BTransportInfoElement.ProxyError());
|
return createTransportInfo(transport, JingleS5BTransportInfoElement.ProxyError.INSTANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
JingleElement createCandidateActivated(JingleS5BTransport transport, JingleS5BTransportCandidate candidate) {
|
JingleElement createCandidateActivated(JingleS5BTransport transport, JingleS5BTransportCandidate candidate) {
|
||||||
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateActivated(candidate.getCandidateId()));
|
return createTransportInfo(transport, new JingleS5BTransportInfoElement.CandidateActivated(candidate.getCandidateId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setUseLocalCandidates(boolean localCandidates) {
|
public static void setUseLocalCandidates(boolean localCandidates) {
|
||||||
|
|
|
@ -135,5 +135,23 @@ public class JingleS5BTransportElement extends JingleContentTransportElement {
|
||||||
public JingleS5BTransportElement build() {
|
public JingleS5BTransportElement build() {
|
||||||
return new JingleS5BTransportElement(streamId, candidates, info, dstAddr, mode);
|
return new JingleS5BTransportElement(streamId, candidates, info, dstAddr, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder setCandidateUsed(String candidateId) {
|
||||||
|
return setTransportInfo(new JingleS5BTransportInfoElement.CandidateUsed(candidateId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setCandidateActivated(String candidateId) {
|
||||||
|
return setTransportInfo(new JingleS5BTransportInfoElement.CandidateActivated(candidateId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setCandidateError() {
|
||||||
|
return setTransportInfo(JingleS5BTransportInfoElement.CandidateError.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder setProxyError() {
|
||||||
|
return setTransportInfo(JingleS5BTransportInfoElement.ProxyError.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,112 +24,76 @@ import org.jivesoftware.smackx.jingle.element.JingleContentTransportInfoElement;
|
||||||
*/
|
*/
|
||||||
public abstract class JingleS5BTransportInfoElement extends JingleContentTransportInfoElement {
|
public abstract class JingleS5BTransportInfoElement extends JingleContentTransportInfoElement {
|
||||||
|
|
||||||
private static CandidateError CEI;
|
public static abstract class JingleS5BCandidateTransportInfoElement extends JingleS5BTransportInfoElement {
|
||||||
private static ProxyError PEI;
|
|
||||||
|
|
||||||
public static CandidateUsed CandidateUsed(String candidateId) {
|
|
||||||
return new CandidateUsed(candidateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CandidateActivated CandidateActivated(String candidateId) {
|
|
||||||
return new CandidateActivated(candidateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CandidateError CandidateError() {
|
|
||||||
if (CEI == null) {
|
|
||||||
CEI = new CandidateError();
|
|
||||||
}
|
|
||||||
return CEI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ProxyError ProxyError() {
|
|
||||||
if (PEI == null) {
|
|
||||||
PEI = new ProxyError();
|
|
||||||
}
|
|
||||||
return PEI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class CandidateActivated extends JingleS5BTransportInfoElement {
|
|
||||||
public static final String ELEMENT = "candidate-activated";
|
|
||||||
public static final String ATTR_CID = "cid";
|
public static final String ATTR_CID = "cid";
|
||||||
|
|
||||||
private final String candidateId;
|
private final String candidateId;
|
||||||
|
|
||||||
|
protected JingleS5BCandidateTransportInfoElement(String candidateId) {
|
||||||
|
this.candidateId = candidateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getCandidateId() {
|
||||||
|
return candidateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final XmlStringBuilder toXML() {
|
||||||
|
XmlStringBuilder xml = new XmlStringBuilder();
|
||||||
|
xml.halfOpenElement(this);
|
||||||
|
xml.attribute(ATTR_CID, getCandidateId());
|
||||||
|
xml.closeEmptyElement();
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean equals(Object other) {
|
||||||
|
if (!(other instanceof JingleS5BCandidateTransportInfoElement)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JingleS5BCandidateTransportInfoElement otherCandidateTransportInfo = (JingleS5BCandidateTransportInfoElement) other;
|
||||||
|
return toXML().equals(otherCandidateTransportInfo.toXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int hashCode() {
|
||||||
|
return getCandidateId().hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class CandidateActivated extends JingleS5BCandidateTransportInfoElement {
|
||||||
|
public static final String ELEMENT = "candidate-activated";
|
||||||
|
|
||||||
public CandidateActivated(String candidateId) {
|
public CandidateActivated(String candidateId) {
|
||||||
this.candidateId = candidateId;
|
super(candidateId);
|
||||||
}
|
|
||||||
|
|
||||||
public String getCandidateId() {
|
|
||||||
return candidateId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence toXML() {
|
|
||||||
XmlStringBuilder xml = new XmlStringBuilder();
|
|
||||||
xml.halfOpenElement(this);
|
|
||||||
xml.attribute(ATTR_CID, candidateId);
|
|
||||||
xml.closeEmptyElement();
|
|
||||||
return xml;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
return other instanceof CandidateActivated &&
|
|
||||||
((CandidateActivated) other).getCandidateId().equals(candidateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public static final class CandidateUsed extends JingleS5BCandidateTransportInfoElement {
|
||||||
public int hashCode() {
|
|
||||||
return toXML().toString().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class CandidateUsed extends JingleS5BTransportInfoElement {
|
|
||||||
public static final String ELEMENT = "candidate-used";
|
public static final String ELEMENT = "candidate-used";
|
||||||
public static final String ATTR_CID = "cid";
|
|
||||||
|
|
||||||
private final String candidateId;
|
|
||||||
|
|
||||||
public CandidateUsed(String candidateId) {
|
public CandidateUsed(String candidateId) {
|
||||||
this.candidateId = candidateId;
|
super(candidateId);
|
||||||
}
|
|
||||||
|
|
||||||
public String getCandidateId() {
|
|
||||||
return candidateId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CharSequence toXML() {
|
|
||||||
XmlStringBuilder xml = new XmlStringBuilder();
|
|
||||||
xml.halfOpenElement(this);
|
|
||||||
xml.attribute(ATTR_CID, candidateId);
|
|
||||||
xml.closeEmptyElement();
|
|
||||||
return xml;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
return other instanceof CandidateUsed &&
|
|
||||||
((CandidateUsed) other).getCandidateId().equals(candidateId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return toXML().toString().hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class CandidateError extends JingleS5BTransportInfoElement {
|
public static final class CandidateError extends JingleS5BTransportInfoElement {
|
||||||
|
|
||||||
|
public static final CandidateError INSTANCE = new CandidateError();
|
||||||
|
|
||||||
public static final String ELEMENT = "candidate-error";
|
public static final String ELEMENT = "candidate-error";
|
||||||
|
|
||||||
private CandidateError() {
|
private CandidateError() {
|
||||||
|
@ -142,7 +106,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence toXML() {
|
public XmlStringBuilder toXML() {
|
||||||
XmlStringBuilder xml = new XmlStringBuilder();
|
XmlStringBuilder xml = new XmlStringBuilder();
|
||||||
xml.halfOpenElement(this);
|
xml.halfOpenElement(this);
|
||||||
xml.closeEmptyElement();
|
xml.closeEmptyElement();
|
||||||
|
@ -151,7 +115,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
return other instanceof CandidateError;
|
return other == INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,7 +124,10 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final class ProxyError extends JingleS5BTransportInfoElement {
|
public static final class ProxyError extends JingleS5BTransportInfoElement {
|
||||||
|
public static final ProxyError INSTANCE = new ProxyError();
|
||||||
|
|
||||||
public static final String ELEMENT = "proxy-error";
|
public static final String ELEMENT = "proxy-error";
|
||||||
|
|
||||||
private ProxyError() {
|
private ProxyError() {
|
||||||
|
@ -173,7 +140,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence toXML() {
|
public XmlStringBuilder toXML() {
|
||||||
XmlStringBuilder xml = new XmlStringBuilder();
|
XmlStringBuilder xml = new XmlStringBuilder();
|
||||||
xml.halfOpenElement(this);
|
xml.halfOpenElement(this);
|
||||||
xml.closeEmptyElement();
|
xml.closeEmptyElement();
|
||||||
|
@ -182,7 +149,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
return other instanceof ProxyError;
|
return other == INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -85,23 +85,23 @@ public class JingleS5BTransportProvider extends JingleContentTransportProvider<J
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
|
||||||
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateActivated(
|
builder.setTransportInfo(new JingleS5BTransportInfoElement.CandidateActivated(
|
||||||
parser.getAttributeValue(null,
|
parser.getAttributeValue(null,
|
||||||
JingleS5BTransportInfoElement.CandidateActivated.ATTR_CID)));
|
JingleS5BTransportInfoElement.JingleS5BCandidateTransportInfoElement.ATTR_CID)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
|
||||||
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateUsed(
|
builder.setTransportInfo(new JingleS5BTransportInfoElement.CandidateUsed(
|
||||||
parser.getAttributeValue(null,
|
parser.getAttributeValue(null,
|
||||||
JingleS5BTransportInfoElement.CandidateUsed.ATTR_CID)));
|
JingleS5BTransportInfoElement.JingleS5BCandidateTransportInfoElement.ATTR_CID)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
|
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
|
||||||
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateError());
|
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateError.INSTANCE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
|
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
|
||||||
builder.setTransportInfo(JingleS5BTransportInfoElement.ProxyError());
|
builder.setTransportInfo(JingleS5BTransportInfoElement.ProxyError.INSTANCE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.jingle;
|
package org.jivesoftware.smackx.jingle.provider;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
import static junit.framework.TestCase.assertEquals;
|
||||||
import static junit.framework.TestCase.assertNull;
|
import static junit.framework.TestCase.assertNull;
|
||||||
|
|
||||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||||
|
import org.jivesoftware.smackx.jingle.JingleManager;
|
||||||
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.JingleIBBTransport;
|
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.JingleIBBTransport;
|
||||||
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.provider.JingleIBBTransportProvider;
|
import org.jivesoftware.smackx.jingle.transport.jingle_ibb.provider.JingleIBBTransportProvider;
|
||||||
import org.jivesoftware.smackx.jingle.transport.jingle_s5b.JingleS5BTransport;
|
import org.jivesoftware.smackx.jingle.transport.jingle_s5b.JingleS5BTransport;
|
|
@ -0,0 +1,121 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 2017 Florian Schmaus, Paul Schaub
|
||||||
|
*
|
||||||
|
* 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.smackx.jingle.provider;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.JingleContentTransportElement;
|
||||||
|
import org.jivesoftware.smackx.jingle.element.JingleElement;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
public class JingleProviderTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseUnknownJingleContentDescrption() throws Exception {
|
||||||
|
final String unknownJingleContentDescriptionNamespace = "urn:xmpp:jingle:unknown-description:5";
|
||||||
|
final String unknownJingleContentDescription =
|
||||||
|
// @formatter:off
|
||||||
|
"<description xmlns='" + unknownJingleContentDescriptionNamespace + "'>" +
|
||||||
|
"<file>" +
|
||||||
|
"<date>1969-07-21T02:56:15Z</date>" +
|
||||||
|
"<desc>This is a test. If this were a real file...</desc>" +
|
||||||
|
"<media-type>text/plain</media-type>" +
|
||||||
|
"<name>test.txt</name>" +
|
||||||
|
"<range/>" +
|
||||||
|
"<size>6144</size>" +
|
||||||
|
"<hash xmlns='urn:xmpp:hashes:2'" +
|
||||||
|
" algo='sha-1'>w0mcJylzCn+AfvuGdqkty2+KP48=</hash>" +
|
||||||
|
"</file>" +
|
||||||
|
"</description>";
|
||||||
|
// @formatter:on
|
||||||
|
XmlPullParser parser = createTestJingle(unknownJingleContentDescription);
|
||||||
|
JingleElement jingle = (JingleElement) PacketParserUtils.parseIQ(parser);
|
||||||
|
|
||||||
|
JingleContentDescriptionElement jingleContentDescription = jingle.getSoleContentOrThrow().getDescription();
|
||||||
|
|
||||||
|
String parsedUnknownJingleContentDescrptionNamespace = jingleContentDescription.getNamespace();
|
||||||
|
assertEquals(unknownJingleContentDescriptionNamespace, parsedUnknownJingleContentDescrptionNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testParseUnknownJingleContentTransport() throws Exception {
|
||||||
|
final String unknownJingleContentTransportNamespace = "urn:xmpp:jingle:unknown-transport:foo:1";
|
||||||
|
final String unknownJingleContentTransport =
|
||||||
|
// @formatter:off
|
||||||
|
"<transport xmlns='" + unknownJingleContentTransportNamespace + "'" +
|
||||||
|
" mode='tcp'" +
|
||||||
|
" sid='vj3hs98y'>" +
|
||||||
|
"<candidate cid='hft54dqy'" +
|
||||||
|
" host='192.168.4.1'" +
|
||||||
|
" jid='romeo@montague.example/dr4hcr0st3lup4c'" +
|
||||||
|
" port='5086'" +
|
||||||
|
" priority='8257636'" +
|
||||||
|
" type='direct'/>" +
|
||||||
|
"<candidate cid='hutr46fe'" +
|
||||||
|
" host='24.24.24.1'" +
|
||||||
|
" jid='romeo@montague.example/dr4hcr0st3lup4c'" +
|
||||||
|
" port='5087'" +
|
||||||
|
" priority='8258636'" +
|
||||||
|
" type='direct'/>" +
|
||||||
|
"</transport>";
|
||||||
|
// @formatter:on
|
||||||
|
XmlPullParser parser = createTestJingle(unknownJingleContentTransport);
|
||||||
|
JingleElement jingle = (JingleElement) PacketParserUtils.parseIQ(parser);
|
||||||
|
|
||||||
|
JingleContentTransportElement jingleContentTransport = jingle.getSoleContentOrThrow().getTransport();
|
||||||
|
|
||||||
|
String parsedUnknownJingleContentTransportNamespace = jingleContentTransport.getNamespace();
|
||||||
|
assertEquals(unknownJingleContentTransportNamespace, parsedUnknownJingleContentTransportNamespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static XmlPullParser createTestJingle(String... childs) throws XmlPullParserException, IOException {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(// @formatter:off
|
||||||
|
"<iq from='romeo@montague.example/dr4hcr0st3lup4c'" +
|
||||||
|
" id='nzu25s8'" +
|
||||||
|
" to='juliet@capulet.example/yn0cl4bnw0yr3vym'" +
|
||||||
|
" type='set'>" +
|
||||||
|
"<jingle xmlns='urn:xmpp:jingle:1' " +
|
||||||
|
" action='session-initiate' " +
|
||||||
|
" initiator='romeo@montague.example/dr4hcr0st3lup4c' " +
|
||||||
|
" sid='851ba2'>" +
|
||||||
|
"<content creator='initiator' name='a-file-offer' senders='initiator'>"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
|
for (String child : childs) {
|
||||||
|
sb.append(child);
|
||||||
|
}
|
||||||
|
sb.append(// @formatter:off
|
||||||
|
"</content>" +
|
||||||
|
"</jingle>" +
|
||||||
|
"</iq>"
|
||||||
|
// @formatter:on
|
||||||
|
);
|
||||||
|
|
||||||
|
String jingleStanza = sb.toString();
|
||||||
|
|
||||||
|
XmlPullParser parser = PacketParserUtils.getParserFor(jingleStanza);
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,7 +163,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
|
||||||
assertNull(candidateErrorTransport.getDestinationAddress());
|
assertNull(candidateErrorTransport.getDestinationAddress());
|
||||||
assertNotNull(candidateErrorTransport.getInfo());
|
assertNotNull(candidateErrorTransport.getInfo());
|
||||||
assertEquals("vj3hs98y", candidateErrorTransport.getSid());
|
assertEquals("vj3hs98y", candidateErrorTransport.getSid());
|
||||||
assertEquals(JingleS5BTransportInfoElement.CandidateError(),
|
assertEquals(JingleS5BTransportInfoElement.CandidateError.INSTANCE,
|
||||||
candidateErrorTransport.getInfo());
|
candidateErrorTransport.getInfo());
|
||||||
assertEquals(candidateError, candidateErrorTransport.toXML().toString());
|
assertEquals(candidateError, candidateErrorTransport.toXML().toString());
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
|
||||||
assertNotNull(proxyErrorTransport.getInfo());
|
assertNotNull(proxyErrorTransport.getInfo());
|
||||||
assertNotNull(candidateErrorTransport.getInfo());
|
assertNotNull(candidateErrorTransport.getInfo());
|
||||||
assertEquals("vj3hs98y", proxyErrorTransport.getSid());
|
assertEquals("vj3hs98y", proxyErrorTransport.getSid());
|
||||||
assertEquals(JingleS5BTransportInfoElement.ProxyError(),
|
assertEquals(JingleS5BTransportInfoElement.ProxyError.INSTANCE,
|
||||||
proxyErrorTransport.getInfo());
|
proxyErrorTransport.getInfo());
|
||||||
assertEquals(proxyError, proxyErrorTransport.toXML().toString());
|
assertEquals(proxyError, proxyErrorTransport.toXML().toString());
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
|
||||||
JingleS5BTransportElement candidateUsedTransport = new JingleS5BTransportProvider()
|
JingleS5BTransportElement candidateUsedTransport = new JingleS5BTransportProvider()
|
||||||
.parse(TestUtils.getParser(candidateUsed));
|
.parse(TestUtils.getParser(candidateUsed));
|
||||||
assertNotNull(candidateUsedTransport.getInfo());
|
assertNotNull(candidateUsedTransport.getInfo());
|
||||||
assertEquals(JingleS5BTransportInfoElement.CandidateUsed("hr65dqyd"),
|
assertEquals(new JingleS5BTransportInfoElement.CandidateUsed("hr65dqyd"),
|
||||||
candidateUsedTransport.getInfo());
|
candidateUsedTransport.getInfo());
|
||||||
assertEquals("hr65dqyd",
|
assertEquals("hr65dqyd",
|
||||||
((JingleS5BTransportInfoElement.CandidateUsed)
|
((JingleS5BTransportInfoElement.CandidateUsed)
|
||||||
|
@ -204,7 +204,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
|
||||||
assertNotNull(candidateActivatedTransport.getInfo());
|
assertNotNull(candidateActivatedTransport.getInfo());
|
||||||
assertNotNull(candidateErrorTransport.getInfo());
|
assertNotNull(candidateErrorTransport.getInfo());
|
||||||
|
|
||||||
assertEquals(JingleS5BTransportInfoElement.CandidateActivated("hr65dqyd"),
|
assertEquals(new JingleS5BTransportInfoElement.CandidateActivated("hr65dqyd"),
|
||||||
candidateActivatedTransport.getInfo());
|
candidateActivatedTransport.getInfo());
|
||||||
assertEquals("hr65dqyd",
|
assertEquals("hr65dqyd",
|
||||||
((JingleS5BTransportInfoElement.CandidateActivated)
|
((JingleS5BTransportInfoElement.CandidateActivated)
|
||||||
|
|
|
@ -12,6 +12,7 @@ dependencies {
|
||||||
compile project(':smack-extensions')
|
compile project(':smack-extensions')
|
||||||
compile project(':smack-experimental')
|
compile project(':smack-experimental')
|
||||||
compile project(':smack-omemo')
|
compile project(':smack-omemo')
|
||||||
|
compile project(':smack-debug')
|
||||||
compile 'org.reflections:reflections:0.9.9-RC1'
|
compile 'org.reflections:reflections:0.9.9-RC1'
|
||||||
compile 'eu.geekplace.javapinning:java-pinning-java7:1.1.0-alpha1'
|
compile 'eu.geekplace.javapinning:java-pinning-java7:1.1.0-alpha1'
|
||||||
compile "junit:junit:$junitVersion"
|
compile "junit:junit:$junitVersion"
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
|
@ -41,12 +42,20 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
public final class Configuration {
|
public final class Configuration {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(Configuration.class.getName());
|
||||||
|
|
||||||
public enum AccountRegistration {
|
public enum AccountRegistration {
|
||||||
disabled,
|
disabled,
|
||||||
inBandRegistration,
|
inBandRegistration,
|
||||||
serviceAdministration,
|
serviceAdministration,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Debugger {
|
||||||
|
none,
|
||||||
|
console,
|
||||||
|
enhanced,
|
||||||
|
}
|
||||||
|
|
||||||
public final DomainBareJid service;
|
public final DomainBareJid service;
|
||||||
|
|
||||||
public final String serviceTlsPin;
|
public final String serviceTlsPin;
|
||||||
|
@ -75,7 +84,7 @@ public final class Configuration {
|
||||||
|
|
||||||
public final String accountThreePassword;
|
public final String accountThreePassword;
|
||||||
|
|
||||||
public final boolean debug;
|
public final Debugger debugger;
|
||||||
|
|
||||||
public final Set<String> enabledTests;
|
public final Set<String> enabledTests;
|
||||||
|
|
||||||
|
@ -84,7 +93,7 @@ public final class Configuration {
|
||||||
public final Set<String> testPackages;
|
public final Set<String> testPackages;
|
||||||
|
|
||||||
private Configuration(DomainBareJid service, String serviceTlsPin, SecurityMode securityMode, int replyTimeout,
|
private Configuration(DomainBareJid service, String serviceTlsPin, SecurityMode securityMode, int replyTimeout,
|
||||||
boolean debug, String accountOneUsername, String accountOnePassword, String accountTwoUsername,
|
Debugger debugger, String accountOneUsername, String accountOnePassword, String accountTwoUsername,
|
||||||
String accountTwoPassword, String accountThreeUsername, String accountThreePassword, Set<String> enabledTests, Set<String> disabledTests,
|
String accountTwoPassword, String accountThreeUsername, String accountThreePassword, Set<String> enabledTests, Set<String> disabledTests,
|
||||||
Set<String> testPackages, String adminAccountUsername, String adminAccountPassword)
|
Set<String> testPackages, String adminAccountUsername, String adminAccountPassword)
|
||||||
throws KeyManagementException, NoSuchAlgorithmException {
|
throws KeyManagementException, NoSuchAlgorithmException {
|
||||||
|
@ -102,7 +111,7 @@ public final class Configuration {
|
||||||
} else {
|
} else {
|
||||||
this.replyTimeout = 60000;
|
this.replyTimeout = 60000;
|
||||||
}
|
}
|
||||||
this.debug = debug;
|
this.debugger = debugger;
|
||||||
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
|
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
|
||||||
accountRegistration = AccountRegistration.serviceAdministration;
|
accountRegistration = AccountRegistration.serviceAdministration;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +171,7 @@ public final class Configuration {
|
||||||
|
|
||||||
public String accountThreePassword;
|
public String accountThreePassword;
|
||||||
|
|
||||||
private boolean debug;
|
private Debugger debugger = Debugger.none;
|
||||||
|
|
||||||
private Set<String> enabledTests;
|
private Set<String> enabledTests;
|
||||||
|
|
||||||
|
@ -247,9 +256,27 @@ public final class Configuration {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder setDebug(String debugString) {
|
@SuppressWarnings("fallthrough")
|
||||||
if (debugString != null) {
|
public Builder setDebugger(String debuggerString) {
|
||||||
debug = Boolean.valueOf(debugString);
|
if (debuggerString == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
switch (debuggerString) {
|
||||||
|
case "false": // For backwards compatibility settings with previous boolean setting.
|
||||||
|
LOGGER.warning("Debug string \"" + debuggerString + "\" is deprecated, please use \"none\" instead");
|
||||||
|
case "none":
|
||||||
|
debugger = Debugger.none;
|
||||||
|
break;
|
||||||
|
case "true": // For backwards compatibility settings with previous boolean setting.
|
||||||
|
LOGGER.warning("Debug string \"" + debuggerString + "\" is deprecated, please use \"console\" instead");
|
||||||
|
case "console":
|
||||||
|
debugger = Debugger.console;
|
||||||
|
break;
|
||||||
|
case "enhanced":
|
||||||
|
debugger = Debugger.enhanced;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("Unrecognized debugger string: " + debuggerString);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +318,7 @@ public final class Configuration {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Configuration build() throws KeyManagementException, NoSuchAlgorithmException {
|
public Configuration build() throws KeyManagementException, NoSuchAlgorithmException {
|
||||||
return new Configuration(service, serviceTlsPin, securityMode, replyTimeout, debug, accountOneUsername,
|
return new Configuration(service, serviceTlsPin, securityMode, replyTimeout, debugger, accountOneUsername,
|
||||||
accountOnePassword, accountTwoUsername, accountTwoPassword, accountThreeUsername, accountThreePassword, enabledTests, disabledTests,
|
accountOnePassword, accountTwoUsername, accountTwoPassword, accountThreeUsername, accountThreePassword, enabledTests, disabledTests,
|
||||||
testPackages, adminAccountUsername, adminAccountPassword);
|
testPackages, adminAccountUsername, adminAccountPassword);
|
||||||
}
|
}
|
||||||
|
@ -346,7 +373,12 @@ public final class Configuration {
|
||||||
accountTwoPassword, accountThreeUsername, accountThreePassword);
|
accountTwoPassword, accountThreeUsername, accountThreePassword);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.setDebug(properties.getProperty("debug"));
|
String debugString = properties.getProperty("debug");
|
||||||
|
if (debugString != null) {
|
||||||
|
LOGGER.warning("Usage of depreacted 'debug' option detected, please use 'debugger' instead");
|
||||||
|
builder.setDebugger(debugString);
|
||||||
|
}
|
||||||
|
builder.setDebugger(properties.getProperty("debugger"));
|
||||||
builder.setEnabledTests(properties.getProperty("enabledTests"));
|
builder.setEnabledTests(properties.getProperty("enabledTests"));
|
||||||
builder.setDisabledTests(properties.getProperty("disabledTests"));
|
builder.setDisabledTests(properties.getProperty("disabledTests"));
|
||||||
|
|
||||||
|
|
|
@ -48,11 +48,14 @@ import org.jivesoftware.smack.SmackConfiguration;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
|
import org.jivesoftware.smack.debugger.ConsoleDebugger;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
|
||||||
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration.Builder;
|
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration.Builder;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.debugger.EnhancedDebugger;
|
||||||
|
import org.jivesoftware.smackx.debugger.EnhancedDebuggerWindow;
|
||||||
import org.jivesoftware.smackx.iqregister.AccountManager;
|
import org.jivesoftware.smackx.iqregister.AccountManager;
|
||||||
|
|
||||||
import org.igniterealtime.smack.inttest.IntTestUtil.UsernameAndPassword;
|
import org.igniterealtime.smack.inttest.IntTestUtil.UsernameAndPassword;
|
||||||
|
@ -98,6 +101,8 @@ public class SmackIntegrationTestFramework {
|
||||||
final int possibleTests = testRunResult.getNumberOfPossibleTests();
|
final int possibleTests = testRunResult.getNumberOfPossibleTests();
|
||||||
LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + ": Finished ["
|
LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + ": Finished ["
|
||||||
+ successfulTests + '/' + possibleTests + "] (of " + availableTests + " available tests)");
|
+ successfulTests + '/' + possibleTests + "] (of " + availableTests + " available tests)");
|
||||||
|
|
||||||
|
int exitStatus;
|
||||||
if (!testRunResult.failedIntegrationTests.isEmpty()) {
|
if (!testRunResult.failedIntegrationTests.isEmpty()) {
|
||||||
final int failedTests = testRunResult.failedIntegrationTests.size();
|
final int failedTests = testRunResult.failedIntegrationTests.size();
|
||||||
LOGGER.warning("The following " + failedTests + " tests failed!");
|
LOGGER.warning("The following " + failedTests + " tests failed!");
|
||||||
|
@ -108,11 +113,21 @@ public class SmackIntegrationTestFramework {
|
||||||
final Throwable cause = failedTest.failureReason;
|
final Throwable cause = failedTest.failureReason;
|
||||||
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
|
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
|
||||||
}
|
}
|
||||||
System.exit(2);
|
exitStatus = 2;
|
||||||
} else {
|
} else {
|
||||||
LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/");
|
LOGGER.info("All possible Smack Integration Tests completed successfully. \\o/");
|
||||||
|
exitStatus = 0;
|
||||||
}
|
}
|
||||||
System.exit(0);
|
|
||||||
|
switch (config.debugger) {
|
||||||
|
case enhanced:
|
||||||
|
EnhancedDebuggerWindow.getInstance().waitUntilClosed();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(exitStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SmackIntegrationTestFramework(Configuration configuration) {
|
public SmackIntegrationTestFramework(Configuration configuration) {
|
||||||
|
@ -123,7 +138,7 @@ public class SmackIntegrationTestFramework {
|
||||||
IOException, XMPPException, InterruptedException {
|
IOException, XMPPException, InterruptedException {
|
||||||
testRunResult = new TestRunResult();
|
testRunResult = new TestRunResult();
|
||||||
LOGGER.info("SmackIntegrationTestFramework [" + testRunResult.testRunId + ']' + ": Starting");
|
LOGGER.info("SmackIntegrationTestFramework [" + testRunResult.testRunId + ']' + ": Starting");
|
||||||
if (config.debug) {
|
if (config.debugger != Configuration.Debugger.none) {
|
||||||
// JUL Debugger will not print any information until configured to print log messages of
|
// JUL Debugger will not print any information until configured to print log messages of
|
||||||
// level FINE
|
// level FINE
|
||||||
// TODO configure JUL for log?
|
// TODO configure JUL for log?
|
||||||
|
@ -583,6 +598,19 @@ public class SmackIntegrationTestFramework {
|
||||||
}
|
}
|
||||||
builder.setSecurityMode(config.securityMode);
|
builder.setSecurityMode(config.securityMode);
|
||||||
builder.setXmppDomain(config.service);
|
builder.setXmppDomain(config.service);
|
||||||
|
|
||||||
|
switch (config.debugger) {
|
||||||
|
case enhanced:
|
||||||
|
builder.setDebuggerFactory(EnhancedDebugger.Factory.INSTANCE);
|
||||||
|
break;
|
||||||
|
case console:
|
||||||
|
builder.setDebuggerFactory(ConsoleDebugger.Factory.INSTANCE);
|
||||||
|
break;
|
||||||
|
case none:
|
||||||
|
// Nothing to do :).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
XMPPTCPConnection connection = new XMPPTCPConnection(builder.build());
|
XMPPTCPConnection connection = new XMPPTCPConnection(builder.build());
|
||||||
connection.connect();
|
connection.connect();
|
||||||
UsernameAndPassword uap = IntTestUtil.registerAccount(connection, environment, connectionId);
|
UsernameAndPassword uap = IntTestUtil.registerAccount(connection, environment, connectionId);
|
||||||
|
|
|
@ -67,11 +67,11 @@ public class IoT {
|
||||||
final XMPPTCPConnectionConfiguration dataThingConnectionConfiguration = XMPPTCPConnectionConfiguration.builder()
|
final XMPPTCPConnectionConfiguration dataThingConnectionConfiguration = XMPPTCPConnectionConfiguration.builder()
|
||||||
.setUsernameAndPassword(dataThingJid.getLocalpart(), dataThingPassword)
|
.setUsernameAndPassword(dataThingJid.getLocalpart(), dataThingPassword)
|
||||||
.setXmppDomain(dataThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
|
.setXmppDomain(dataThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
|
||||||
.setDebuggerEnabled(true).build();
|
.enableDefaultDebugger().build();
|
||||||
final XMPPTCPConnectionConfiguration readingThingConnectionConfiguration = XMPPTCPConnectionConfiguration
|
final XMPPTCPConnectionConfiguration readingThingConnectionConfiguration = XMPPTCPConnectionConfiguration
|
||||||
.builder().setUsernameAndPassword(readingThingJid.getLocalpart(), readingThingPassword)
|
.builder().setUsernameAndPassword(readingThingJid.getLocalpart(), readingThingPassword)
|
||||||
.setXmppDomain(readingThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
|
.setXmppDomain(readingThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
|
||||||
.setDebuggerEnabled(true).build();
|
.enableDefaultDebugger().build();
|
||||||
|
|
||||||
final XMPPTCPConnection dataThingConnection = new XMPPTCPConnection(dataThingConnectionConfiguration);
|
final XMPPTCPConnection dataThingConnection = new XMPPTCPConnection(dataThingConnectionConfiguration);
|
||||||
final XMPPTCPConnection readingThingConnection = new XMPPTCPConnection(readingThingConnectionConfiguration);
|
final XMPPTCPConnection readingThingConnection = new XMPPTCPConnection(readingThingConnectionConfiguration);
|
||||||
|
|
|
@ -79,7 +79,9 @@ public class TlsTest {
|
||||||
.setPort(port)
|
.setPort(port)
|
||||||
.setSecurityMode(SecurityMode.required);
|
.setSecurityMode(SecurityMode.required);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
builder.setDebuggerEnabled(DEBUG);
|
if (DEBUG) {
|
||||||
|
builder.enableDefaultDebugger();
|
||||||
|
}
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(tlsPin)) {
|
if (StringUtils.isNotEmpty(tlsPin)) {
|
||||||
SSLContext sslContext = Java7Pinning.forPin(tlsPin);
|
SSLContext sslContext = Java7Pinning.forPin(tlsPin);
|
||||||
|
|
|
@ -636,15 +636,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
if (isFirstInitialization) {
|
if (isFirstInitialization) {
|
||||||
packetWriter = new PacketWriter();
|
packetWriter = new PacketWriter();
|
||||||
packetReader = new PacketReader();
|
packetReader = new PacketReader();
|
||||||
|
|
||||||
// If debugging is enabled, we should start the thread that will listen for
|
|
||||||
// all packets and then log them.
|
|
||||||
if (config.isDebuggerEnabled()) {
|
|
||||||
addAsyncStanzaListener(debugger.getReaderListener(), null);
|
|
||||||
if (debugger.getWriterListener() != null) {
|
|
||||||
addPacketSendingListener(debugger.getWriterListener(), null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Start the packet writer. This will open an XMPP stream to the server
|
// Start the packet writer. This will open an XMPP stream to the server
|
||||||
packetWriter.init();
|
packetWriter.init();
|
||||||
|
|
Loading…
Reference in a new issue