1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-24 04:52:05 +01:00

Merge flowdalic/master

This commit is contained in:
vanitasvitae 2017-08-05 18:22:07 +02:00
commit 9712dc1df7
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
40 changed files with 714 additions and 544 deletions

View file

@ -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 |

View file

@ -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

View file

@ -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

View file

@ -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() {

View file

@ -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();
} }
} }

View file

@ -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.
* *

View file

@ -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;
}
} }

View file

@ -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);
}
}
} }

View file

@ -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

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -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);
} }
} }

View file

@ -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());
}
}
}

View file

@ -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;
}
} }

View file

@ -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);
}
}
} }

View file

@ -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();
}
}
} }

View file

@ -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;
}
} }

View file

@ -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);

View 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();

View file

@ -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;

View file

@ -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);

View file

@ -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());

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}
} }
} }

View file

@ -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

View file

@ -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;
} }
} }

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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"

View file

@ -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"));

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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();