1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-12-24 19:47:58 +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
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
debug=true
debugger=console
```
### Framework properties
@ -72,7 +72,7 @@ debug=true
| accountTwoPassword | Password of the second XMPP account |
| accountThreeUsername | Username 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 |
| disabledTests | List of disabled tests |
| testPackages | List of packages with tests |

View file

@ -16,9 +16,6 @@
*/
package org.jivesoftware.smackx.debugger.android;
import java.io.Reader;
import java.io.Writer;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.debugger.AbstractDebugger;
@ -37,8 +34,8 @@ import android.util.Log;
*/
public class AndroidDebugger extends AbstractDebugger {
public AndroidDebugger(XMPPConnection connection, Writer writer, Reader reader) {
super(connection, writer, reader);
public AndroidDebugger(XMPPConnection connection) {
super(connection);
}
@Override

View file

@ -161,16 +161,8 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
client.addBOSHClientResponseListener(new BOSHPacketReader());
// Initialize the debugger
if (config.isDebuggerEnabled()) {
if (debugger != null) {
initDebugger();
if (isFirstInitialization) {
if (debugger.getReaderListener() != null) {
addAsyncStanzaListener(debugger.getReaderListener(), null);
}
if (debugger.getWriterListener() != null) {
addPacketSendingListener(debugger.getWriterListener(), null);
}
}
}
// 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.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
import org.jivesoftware.smack.filter.IQReplyFilter;
import org.jivesoftware.smack.filter.StanzaFilter;
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.
*/
protected SmackDebugger debugger = null;
protected final SmackDebugger debugger;
/**
* The Reader which is used for the debugger.
@ -301,6 +302,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
protected AbstractXMPPConnection(ConnectionConfiguration configuration) {
saslAuthentication = new SASLAuthentication(this, 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
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
listener.connectionCreated(this);
@ -568,7 +575,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
// name we are now logged-in as.
// If DEBUG was set to true AFTER the connection was created the debugger
// will be null
if (config.isDebuggerEnabled() && debugger != null) {
if (debugger != null) {
debugger.userHasLogged(user);
}
callConnectionAuthenticatedListener(resumed);
@ -872,6 +879,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
*/
@SuppressWarnings("javadoc")
protected void firePacketSendingListeners(final Stanza packet) {
final SmackDebugger debugger = this.debugger;
if (debugger != null) {
debugger.onOutgoingStreamElement(packet);
}
final List<StanzaListener> listenersToNotify = new LinkedList<StanzaListener>();
synchronized (sendListeners) {
for (ListenerWrapper listenerWrapper : sendListeners.values()) {
@ -957,18 +969,10 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
throw new NullPointerException("Reader or writer isn't initialized.");
}
// If debugging is enabled, we open a window and write out all network traffic.
if (config.isDebuggerEnabled()) {
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
reader = debugger.newConnectionReader(reader);
writer = debugger.newConnectionWriter(writer);
}
if (debugger != null) {
// Obtain new reader and writer from the existing debugger
reader = debugger.newConnectionReader(reader);
writer = debugger.newConnectionWriter(writer);
}
}
@ -1072,6 +1076,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
*/
protected void processStanza(final Stanza stanza) throws InterruptedException {
assert (stanza != null);
final SmackDebugger debugger = this.debugger;
if (debugger != null) {
debugger.onIncomingStreamElement(stanza);
}
lastStanzaReceived = System.currentTimeMillis();
// Deliver the incoming packet to listeners.
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");
* 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.security.auth.callback.CallbackHandler;
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.sasl.SASLMechanism;
@ -78,7 +79,7 @@ public abstract class ConnectionConfiguration {
*/
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
private final SocketFactory socketFactory;
@ -158,7 +159,7 @@ public abstract class ConnectionConfiguration {
hostnameVerifier = builder.hostnameVerifier;
sendPresence = builder.sendPresence;
legacySessionDisabled = builder.legacySessionDisabled;
debuggerEnabled = builder.debuggerEnabled;
debuggerFactory = builder.debuggerFactory;
allowNullOrEmptyUsername = builder.allowEmptyOrNullUsername;
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
* default the value of {@link SmackConfiguration#DEBUG} is used.
* Returns the Smack debugger factory.
*
* @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() {
return debuggerEnabled;
public SmackDebuggerFactory getDebuggerFactory() {
return debuggerFactory;
}
/**
@ -519,7 +519,7 @@ public abstract class ConnectionConfiguration {
private boolean legacySessionDisabled = false;
private ProxyInfo proxy;
private CallbackHandler callbackHandler;
private boolean debuggerEnabled = SmackConfiguration.DEBUG;
private SmackDebuggerFactory debuggerFactory;
private SocketFactory socketFactory;
private DomainBareJid xmppServiceDomain;
private InetAddress hostAddress;
@ -531,6 +531,9 @@ public abstract class ConnectionConfiguration {
private X509TrustManager customX509TrustManager;
protected Builder() {
if (SmackConfiguration.DEBUG) {
enableDefaultDebugger();
}
}
/**
@ -808,15 +811,20 @@ public abstract class ConnectionConfiguration {
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
* default the value of {@link SmackConfiguration#DEBUG} is used.
*
* @param debuggerEnabled if the new connection about to be establish is going to be debugged.
* Set the Smack debugger factory used to construct Smack debuggers.
*
* @param debuggerFactory the Smack debugger factory.
* @return a reference to this builder.
*/
public B setDebuggerEnabled(boolean debuggerEnabled) {
this.debuggerEnabled = debuggerEnabled;
public B setDebuggerFactory(SmackDebuggerFactory debuggerFactory) {
this.debuggerFactory = debuggerFactory;
return getThis();
}
@ -965,4 +973,5 @@ public abstract class ConnectionConfiguration {
protected abstract B getThis();
}
}

View file

@ -17,8 +17,6 @@
package org.jivesoftware.smack;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -30,7 +28,6 @@ import javax.net.ssl.HostnameVerifier;
import org.jivesoftware.smack.compression.XMPPInputOutputStream;
import org.jivesoftware.smack.debugger.ReflectionDebuggerFactory;
import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
import org.jivesoftware.smack.parsing.ExceptionThrowingCallback;
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
@ -63,8 +60,6 @@ public final class SmackConfiguration {
static boolean smackInitialized = false;
private static SmackDebuggerFactory debuggerFactory = new ReflectionDebuggerFactory();
/**
* Value that indicates whether debugging is enabled. When enabled, a debug
* 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;
private static SmackDebuggerFactory DEFAULT_DEBUGGER_FACTORY = ReflectionDebuggerFactory.INSTANCE;
/**
* The default parsing exception callback is {@link ExceptionThrowingCallback} which will
* throw an exception and therefore disconnect the active connection.
@ -148,6 +145,14 @@ public final class SmackConfiguration {
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
* 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.
*

View file

@ -20,9 +20,8 @@ import java.io.Reader;
import java.io.Writer;
import org.jivesoftware.smack.ConnectionListener;
import org.jivesoftware.smack.StanzaListener;
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.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener;
@ -30,13 +29,10 @@ import org.jivesoftware.smack.util.WriterListener;
import org.jxmpp.jid.EntityFullJid;
public abstract class AbstractDebugger implements SmackDebugger {
public abstract class AbstractDebugger extends SmackDebugger {
public static boolean printInterpreted = false;
private final XMPPConnection connection;
private final StanzaListener listener;
private final ConnectionListener connListener;
private final ReaderListener readerListener;
private final WriterListener writerListener;
@ -44,8 +40,8 @@ public abstract class AbstractDebugger implements SmackDebugger {
private ObservableWriter writer;
private ObservableReader reader;
public AbstractDebugger(final XMPPConnection connection, Writer writer, Reader reader) {
this.connection = connection;
public AbstractDebugger(final XMPPConnection connection) {
super(connection);
// Create a special Reader that wraps the main Reader and logs data to the GUI.
this.reader = new ObservableReader(reader);
@ -67,18 +63,6 @@ public abstract class AbstractDebugger implements SmackDebugger {
};
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() {
@Override
public void connected(XMPPConnection connection) {
@ -173,22 +157,15 @@ public abstract class AbstractDebugger implements SmackDebugger {
}
@Override
public Reader getReader() {
return reader;
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
if (printInterpreted) {
log("RCV PKT (" + connection.getConnectionCounter() + "): " + streamElement.toXML());
}
}
@Override
public Writer getWriter() {
return writer;
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
// 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;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
@ -39,8 +37,8 @@ import org.jivesoftware.smack.XMPPConnection;
public class ConsoleDebugger extends AbstractDebugger {
private final SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss");
public ConsoleDebugger(XMPPConnection connection, Writer writer, Reader reader) {
super(connection, writer, reader);
public ConsoleDebugger(XMPPConnection connection) {
super(connection);
}
@Override
@ -64,4 +62,17 @@ public class ConsoleDebugger extends AbstractDebugger {
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");
* you may not use this file except in compliance with the License.
@ -16,8 +16,6 @@
*/
package org.jivesoftware.smack.debugger;
import java.io.Reader;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -38,8 +36,8 @@ public class JulDebugger extends AbstractDebugger {
private static final Logger LOGGER = Logger.getLogger(JulDebugger.class.getName());
public JulDebugger(XMPPConnection connection, Writer writer, Reader reader) {
super(connection, writer, reader);
public JulDebugger(XMPPConnection connection) {
super(connection);
}
@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");
* 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
* limitations under the License.
*/
package org.jivesoftware.smack.debugger;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Constructor;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -27,10 +23,15 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.SmackConfiguration;
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 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
* to instantiate these.
@ -76,14 +77,14 @@ public class ReflectionDebuggerFactory implements SmackDebuggerFactory {
}
@Override
public SmackDebugger create(XMPPConnection connection, Writer writer, Reader reader) throws IllegalArgumentException {
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
Class<SmackDebugger> debuggerClass = getDebuggerClass();
if (debuggerClass != null) {
// Create a new debugger instance using 3arg constructor
try {
Constructor<SmackDebugger> constructor = debuggerClass
.getConstructor(XMPPConnection.class, Writer.class, Reader.class);
return constructor.newInstance(connection, writer, reader);
.getConstructor(XMPPConnection.class);
return constructor.newInstance(connection);
} catch (Exception 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");
* 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.Writer;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jxmpp.jid.EntityFullJid;
@ -33,7 +34,13 @@ import org.jxmpp.jid.EntityFullJid;
*
* @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
@ -42,22 +49,9 @@ public interface SmackDebugger {
*
* @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);
/**
* 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
* 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);
/**
* Returns the thread that will listen for all incoming packets and write them to the GUI.
* This is what we call "interpreted" stanza(/packet) data, since it's the stanza(/packet) data as Smack sees
* it and not as it's coming in as raw XML.
*
* @return the PacketListener 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.
* <p>
* This method is invoked right after the incoming stream was parsed.
* </p>
*
* @param streamElement the incoming top level stream element.
*/
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.
*
* @return the PacketListener that will listen for all sent 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>
*
* @param streamElement the outgoing top level stream element.
*/
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");
* 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
* limitations under the License.
*/
package org.jivesoftware.smack.debugger;
import java.io.Reader;
import java.io.Writer;
import org.jivesoftware.smack.XMPPConnection;
public interface SmackDebuggerFactory {
/**
* 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.
*/
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");
* 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("another-element-text", parsedElement.getFirstElement("another-element").getText());
String parsedElementString = parsedElement.toXML().toString();
assertEquals(elementString, parsedElementString);
}
@Test

View file

@ -17,9 +17,6 @@
package org.jivesoftware.smackx.debugger.slf4j;
import java.io.Reader;
import java.io.Writer;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.debugger.SmackDebugger;
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.
*/
public class SLF4JDebuggerFactory implements SmackDebuggerFactory {
public final class SLF4JDebuggerFactory implements SmackDebuggerFactory {
public static final SLF4JDebuggerFactory INSTANCE = new SLF4JDebuggerFactory();
private SLF4JDebuggerFactory() {
}
@Override
public SmackDebugger create(XMPPConnection connection, Writer writer, Reader reader) throws IllegalArgumentException {
return new SLF4JSmackDebugger(connection, writer, reader);
public SmackDebugger create(XMPPConnection connection) throws IllegalArgumentException {
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 org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jivesoftware.smack.util.ObservableReader;
import org.jivesoftware.smack.util.ObservableWriter;
@ -38,7 +38,8 @@ import org.slf4j.LoggerFactory;
* Use in conjunction with your SLF4J bindings of choice.
* 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";
private static final Logger logger = LoggerFactory.getLogger(LOGGER_NAME);
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 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 ObservableWriter writer;
@ -59,17 +56,16 @@ public class SLF4JSmackDebugger implements SmackDebugger {
* Makes Smack use this Debugger.
*/
public static void enable() {
SmackConfiguration.setDebuggerFactory(new SLF4JDebuggerFactory());
SmackConfiguration.DEBUG = true;
SmackConfiguration.setDefaultSmackDebuggerFactory(SLF4JDebuggerFactory.INSTANCE);
}
/**
* Create new SLF4J Smack Debugger instance.
* @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) {
this.connection = connection;
SLF4JSmackDebugger(XMPPConnection connection) {
super(connection);
this.writer = new ObservableWriter(writer);
this.writer.addWriterListener(slf4JRawXmlListener);
this.reader = new ObservableReader(Validate.notNull(reader));
@ -101,22 +97,17 @@ public class SLF4JSmackDebugger implements SmackDebugger {
}
@Override
public Reader getReader() {
return reader;
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
logger.debug("IN {}: {}", streamElement.getClass().getName(), streamElement.toXML());
}
}
@Override
public Writer getWriter() {
return writer;
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
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.ConnectionListener;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.debugger.SmackDebugger;
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.TopLevelStreamElement;
import org.jivesoftware.smack.util.ObservableReader;
import org.jivesoftware.smack.util.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener;
@ -97,7 +98,7 @@ import org.jxmpp.jid.Jid;
*
* @author Gaston Dombiak
*/
public class EnhancedDebugger implements SmackDebugger {
public class EnhancedDebugger extends SmackDebugger {
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 statusField = null;
private XMPPConnection connection = null;
private StanzaListener packetReaderListener = null;
private StanzaListener packetWriterListener = null;
private ConnectionListener connListener = null;
private Writer writer;
@ -177,18 +174,9 @@ public class EnhancedDebugger implements SmackDebugger {
JTabbedPane tabbedPane;
public EnhancedDebugger(XMPPConnection connection, Writer writer, Reader reader) {
this.connection = connection;
this.writer = writer;
this.reader = reader;
createDebug();
EnhancedDebuggerWindow.addDebugger(this);
}
public EnhancedDebugger(XMPPConnection connection) {
super(connection);
/**
* 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
// client generated XML, the third server generated XML, the fourth allows to send
// ad-hoc messages and the fifth contains connection information.
@ -203,41 +191,6 @@ public class EnhancedDebugger implements SmackDebugger {
// Add the connection information panel
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
connListener = new AbstractConnectionListener() {
@Override
@ -294,6 +247,8 @@ public class EnhancedDebugger implements SmackDebugger {
});
}
};
EnhancedDebuggerWindow.addDebugger(this);
}
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
*/
@ -839,12 +774,21 @@ public class EnhancedDebugger implements SmackDebugger {
* @param dateFormatter the SimpleDateFormat to use to format Dates
* @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() {
@Override
public void run() {
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 = "";
Icon packetTypeIcon;
receivedPackets++;
@ -885,7 +829,7 @@ public class EnhancedDebugger implements SmackDebugger {
packetReceivedIcon,
packetTypeIcon,
messageType,
packet.getStanzaId(),
stanzaId,
type,
"",
from});
@ -901,12 +845,21 @@ public class EnhancedDebugger implements SmackDebugger {
* @param dateFormatter the SimpleDateFormat to use to format Dates
* @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() {
@Override
public void run() {
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 = "";
Icon packetTypeIcon;
sentPackets++;
@ -947,7 +900,7 @@ public class EnhancedDebugger implements SmackDebugger {
packetSentIcon,
packetTypeIcon,
messageType,
packet.getStanzaId(),
stanzaId,
type,
to,
""});
@ -1006,8 +959,6 @@ public class EnhancedDebugger implements SmackDebugger {
*/
void cancel() {
connection.removeConnectionListener(connListener);
connection.removeAsyncStanzaListener(packetReaderListener);
connection.removePacketSendingListener(packetWriterListener);
((ObservableReader) reader).removeReaderListener(readerListener);
((ObservableWriter) writer).removeWriterListener(writerListener);
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
*/
public static EnhancedDebuggerWindow getInstance() {
public synchronized static EnhancedDebuggerWindow getInstance() {
if (instance == null) {
instance = new EnhancedDebuggerWindow();
}
@ -345,7 +345,7 @@ public final class EnhancedDebuggerWindow {
*
* @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
for (EnhancedDebugger debugger : debuggers) {
debugger.cancel();
@ -354,6 +354,8 @@ public final class EnhancedDebuggerWindow {
debuggers.clear();
// Release the default instance
instance = null;
frame = null;
notifyAll();
}
/**
@ -393,4 +395,14 @@ public final class EnhancedDebuggerWindow {
public boolean 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.JTextArea;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.XMPPConnection;
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.ObservableWriter;
import org.jivesoftware.smack.util.ReaderListener;
@ -57,24 +56,22 @@ import org.jxmpp.jid.EntityFullJid;
*
* @author Gaston Dombiak
*/
public class LiteDebugger implements SmackDebugger {
public class LiteDebugger extends SmackDebugger {
private static final String NEWLINE = "\n";
private JFrame frame = null;
private XMPPConnection connection = null;
private final JTextArea interpretedText1 = new JTextArea();
private final JTextArea interpretedText2 = new JTextArea();
private StanzaListener listener = null;
private JFrame frame = null;
private Writer writer;
private Reader reader;
private ReaderListener readerListener;
private WriterListener writerListener;
public LiteDebugger(XMPPConnection connection, Writer writer, Reader reader) {
this.connection = connection;
this.writer = writer;
this.reader = reader;
public LiteDebugger(XMPPConnection connection) {
super(connection);
createDebug();
}
@ -181,8 +178,6 @@ public class LiteDebugger implements SmackDebugger {
menu.add(menuItem2);
// Create UI elements for interpreted XML traffic.
final JTextArea interpretedText1 = new JTextArea();
final JTextArea interpretedText2 = new JTextArea();
interpretedText1.setEditable(false);
interpretedText2.setEditable(false);
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.
reader = debugReader;
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
*/
public void rootWindowClosing(WindowEvent evt) {
connection.removeAsyncStanzaListener(listener);
// TODO: Remove debugger from connection.
((ObservableReader) reader).removeReaderListener(readerListener);
((ObservableWriter) writer).removeWriterListener(writerListener);
}
@ -348,22 +330,16 @@ public class LiteDebugger implements SmackDebugger {
}
@Override
public Reader getReader() {
return reader;
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
interpretedText1.append(streamElement.toXML().toString());
interpretedText2.append(streamElement.toXML().toString());
interpretedText1.append(NEWLINE);
interpretedText2.append(NEWLINE);
}
@Override
public Writer getWriter() {
return writer;
public void onOutgoingStreamElement(TopLevelStreamElement streamElement) {
// 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 org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smackx.jft.component.JingleFileTransfer;
import org.jivesoftware.smackx.jft.component.JingleIncomingFileOffer;
import org.jivesoftware.smackx.jft.component.JingleIncomingFileRequest;
import org.jivesoftware.smackx.jft.element.JingleFileTransferChildElement;
import org.jivesoftware.smackx.jft.element.JingleFileTransferElement;
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.JingleContentElement;
@ -37,9 +37,9 @@ public class JingleFileTransferAdapter implements JingleDescriptionAdapter<Jingl
public JingleFileTransfer descriptionFromElement(JingleContentElement.Creator creator, JingleContentElement.Senders senders,
String contentName, String contentDisposition, JingleContentDescriptionElement element) {
JingleFileTransferElement description = (JingleFileTransferElement) element;
List<JingleContentDescriptionChildElement> childs = description.getJingleContentDescriptionChildren();
assert childs.size() == 1;
JingleFileTransferChildElement file = (JingleFileTransferChildElement) childs.get(0);
List<NamedElement> children = description.getJingleContentDescriptionChildren();
assert children.size() == 1;
JingleFileTransferChildElement file = (JingleFileTransferChildElement) children.get(0);
if (senders == JingleContentElement.Senders.initiator) {
return new JingleIncomingFileOffer(file);

View file

@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.List;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
/**
@ -37,9 +38,9 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
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) {
this.payloads = Collections.unmodifiableList(payloads);
}
@ -53,7 +54,7 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
return ELEMENT;
}
public List<JingleContentDescriptionChildElement> getJingleContentDescriptionChildren() {
public List<NamedElement> getJingleContentDescriptionChildren() {
return payloads;
}
@ -66,7 +67,7 @@ public abstract class JingleContentDescriptionElement implements ExtensionElemen
}
@Override
public final XmlStringBuilder toXML() {
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
addExtraAttributes(xml);
xml.rightAngleBracket();

View file

@ -115,9 +115,8 @@ public final class JingleContentElement implements NamedElement {
}
/**
* Returns an Iterator for the JingleTransports in the packet.
*
* @return an Iterator for the JingleTransports in the packet.
* Return the transport of the content.
* @return transport.
*/
public JingleContentTransportElement getTransport() {
return transport;

View file

@ -72,7 +72,7 @@ public abstract class JingleContentTransportElement implements ExtensionElement
}
@Override
public final XmlStringBuilder toXML() {
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
addExtraAttributes(xml);

View file

@ -136,6 +136,18 @@ public final class JingleElement extends IQ {
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
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
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 org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.jingle.JingleManager;
import org.jivesoftware.smackx.jingle.element.JingleAction;
import org.jivesoftware.smackx.jingle.element.JingleContentDescriptionElement;
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.JingleElement;
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.xmlpull.v1.XmlPullParser;
@ -117,48 +120,45 @@ public class JingleProvider extends IQProvider<JingleElement> {
outerloop: while (true) {
int eventType = parser.next();
switch (eventType) {
case XmlPullParser.START_TAG:
String tagName = parser.getName();
String namespace = parser.getNamespace();
switch (tagName) {
case JingleContentDescriptionElement.ELEMENT: {
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
if (provider == null) {
// TODO handle this case (DefaultExtensionElement wrapped in something?)
break;
}
JingleContentDescriptionElement description = provider.parse(parser);
builder.setDescription(description);
break;
}
case JingleContentTransportElement.ELEMENT: {
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
if (provider == null) {
// TODO handle this case (DefaultExtensionElement wrapped in something?)
break;
}
JingleContentTransportElement transport = provider.parse(parser);
builder.setTransport(transport);
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:
LOGGER.severe("Unknown Jingle content element: " + tagName);
break;
case XmlPullParser.START_TAG:
String tagName = parser.getName();
String namespace = parser.getNamespace();
switch (tagName) {
case JingleContentDescriptionElement.ELEMENT: {
JingleContentDescriptionElement description;
JingleContentDescriptionProvider<?> provider = JingleManager.getJingleDescriptionProvider(namespace);
if (provider == null) {
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
description = new UnknownJingleContentDescriptionElement(standardExtensionElement);
}
else {
description = provider.parse(parser);
}
builder.setDescription(description);
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
case JingleContentTransportElement.ELEMENT: {
JingleContentTransportElement transport;
JingleContentTransportProvider<?> provider = JingleManager.getJingleTransportProvider(namespace);
if (provider == null) {
StandardExtensionElement standardExtensionElement = StandardExtensionElementProvider.INSTANCE.parse(parser);
transport = new UnknownJingleContentTransportElement(standardExtensionElement);
}
else {
transport = provider.parse(parser);
}
builder.setTransport(transport);
break;
}
default:
LOGGER.severe("Unknown Jingle content element: " + tagName);
break;
}
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
}
}

View file

@ -65,7 +65,7 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
private List<Bytestream.StreamHost> localStreamHosts = null;
private List<Bytestream.StreamHost> availableStreamHosts = null;
private static boolean useLocalCandidates = false;
private static boolean useLocalCandidates = true;
private static boolean useExternalCandidates = true;
static {
@ -222,19 +222,19 @@ public final class JingleS5BTransportManager extends Manager implements JingleTr
}
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) {
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateError());
return createTransportInfo(transport, JingleS5BTransportInfoElement.CandidateError.INSTANCE);
}
JingleElement createProxyError(JingleS5BTransport transport) {
return createTransportInfo(transport, JingleS5BTransportInfoElement.ProxyError());
return createTransportInfo(transport, JingleS5BTransportInfoElement.ProxyError.INSTANCE);
}
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) {

View file

@ -135,5 +135,23 @@ public class JingleS5BTransportElement extends JingleContentTransportElement {
public JingleS5BTransportElement build() {
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 {
private static CandidateError CEI;
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 abstract class JingleS5BCandidateTransportInfoElement extends JingleS5BTransportInfoElement {
public static final String ATTR_CID = "cid";
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) {
this.candidateId = candidateId;
}
public String getCandidateId() {
return candidateId;
super(candidateId);
}
@Override
public String getElementName() {
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 int hashCode() {
return toXML().toString().hashCode();
}
}
public static final class CandidateUsed extends JingleS5BTransportInfoElement {
public static final String ELEMENT = "candidate-used";
public static final String ATTR_CID = "cid";
private final String candidateId;
public static final class CandidateUsed extends JingleS5BCandidateTransportInfoElement {
public static final String ELEMENT = "candidate-used";
public CandidateUsed(String candidateId) {
this.candidateId = candidateId;
}
public String getCandidateId() {
return candidateId;
super(candidateId);
}
@Override
public String getElementName() {
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 CandidateError INSTANCE = new CandidateError();
public static final String ELEMENT = "candidate-error";
private CandidateError() {
@ -142,7 +106,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
}
@Override
public CharSequence toXML() {
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.closeEmptyElement();
@ -151,7 +115,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
@Override
public boolean equals(Object other) {
return other instanceof CandidateError;
return other == INSTANCE;
}
@Override
@ -160,7 +124,10 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
}
}
public static final class ProxyError extends JingleS5BTransportInfoElement {
public static final ProxyError INSTANCE = new ProxyError();
public static final String ELEMENT = "proxy-error";
private ProxyError() {
@ -173,7 +140,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
}
@Override
public CharSequence toXML() {
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(this);
xml.closeEmptyElement();
@ -182,7 +149,7 @@ public abstract class JingleS5BTransportInfoElement extends JingleContentTranspo
@Override
public boolean equals(Object other) {
return other instanceof ProxyError;
return other == INSTANCE;
}
@Override

View file

@ -85,23 +85,23 @@ public class JingleS5BTransportProvider extends JingleContentTransportProvider<J
break;
case JingleS5BTransportInfoElement.CandidateActivated.ELEMENT:
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateActivated(
builder.setTransportInfo(new JingleS5BTransportInfoElement.CandidateActivated(
parser.getAttributeValue(null,
JingleS5BTransportInfoElement.CandidateActivated.ATTR_CID)));
JingleS5BTransportInfoElement.JingleS5BCandidateTransportInfoElement.ATTR_CID)));
break;
case JingleS5BTransportInfoElement.CandidateUsed.ELEMENT:
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateUsed(
builder.setTransportInfo(new JingleS5BTransportInfoElement.CandidateUsed(
parser.getAttributeValue(null,
JingleS5BTransportInfoElement.CandidateUsed.ATTR_CID)));
JingleS5BTransportInfoElement.JingleS5BCandidateTransportInfoElement.ATTR_CID)));
break;
case JingleS5BTransportInfoElement.CandidateError.ELEMENT:
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateError());
builder.setTransportInfo(JingleS5BTransportInfoElement.CandidateError.INSTANCE);
break;
case JingleS5BTransportInfoElement.ProxyError.ELEMENT:
builder.setTransportInfo(JingleS5BTransportInfoElement.ProxyError());
builder.setTransportInfo(JingleS5BTransportInfoElement.ProxyError.INSTANCE);
break;
}
}

View file

@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* 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.assertNull;
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.provider.JingleIBBTransportProvider;
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());
assertNotNull(candidateErrorTransport.getInfo());
assertEquals("vj3hs98y", candidateErrorTransport.getSid());
assertEquals(JingleS5BTransportInfoElement.CandidateError(),
assertEquals(JingleS5BTransportInfoElement.CandidateError.INSTANCE,
candidateErrorTransport.getInfo());
assertEquals(candidateError, candidateErrorTransport.toXML().toString());
@ -177,7 +177,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
assertNotNull(proxyErrorTransport.getInfo());
assertNotNull(candidateErrorTransport.getInfo());
assertEquals("vj3hs98y", proxyErrorTransport.getSid());
assertEquals(JingleS5BTransportInfoElement.ProxyError(),
assertEquals(JingleS5BTransportInfoElement.ProxyError.INSTANCE,
proxyErrorTransport.getInfo());
assertEquals(proxyError, proxyErrorTransport.toXML().toString());
@ -188,7 +188,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
JingleS5BTransportElement candidateUsedTransport = new JingleS5BTransportProvider()
.parse(TestUtils.getParser(candidateUsed));
assertNotNull(candidateUsedTransport.getInfo());
assertEquals(JingleS5BTransportInfoElement.CandidateUsed("hr65dqyd"),
assertEquals(new JingleS5BTransportInfoElement.CandidateUsed("hr65dqyd"),
candidateUsedTransport.getInfo());
assertEquals("hr65dqyd",
((JingleS5BTransportInfoElement.CandidateUsed)
@ -204,7 +204,7 @@ public class JingleS5BTransportTest extends SmackTestSuite {
assertNotNull(candidateActivatedTransport.getInfo());
assertNotNull(candidateErrorTransport.getInfo());
assertEquals(JingleS5BTransportInfoElement.CandidateActivated("hr65dqyd"),
assertEquals(new JingleS5BTransportInfoElement.CandidateActivated("hr65dqyd"),
candidateActivatedTransport.getInfo());
assertEquals("hr65dqyd",
((JingleS5BTransportInfoElement.CandidateActivated)

View file

@ -12,6 +12,7 @@ dependencies {
compile project(':smack-extensions')
compile project(':smack-experimental')
compile project(':smack-omemo')
compile project(':smack-debug')
compile 'org.reflections:reflections:0.9.9-RC1'
compile 'eu.geekplace.javapinning:java-pinning-java7:1.1.0-alpha1'
compile "junit:junit:$junitVersion"

View file

@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
@ -41,12 +42,20 @@ import org.jxmpp.stringprep.XmppStringprepException;
public final class Configuration {
private static final Logger LOGGER = Logger.getLogger(Configuration.class.getName());
public enum AccountRegistration {
disabled,
inBandRegistration,
serviceAdministration,
}
public enum Debugger {
none,
console,
enhanced,
}
public final DomainBareJid service;
public final String serviceTlsPin;
@ -75,7 +84,7 @@ public final class Configuration {
public final String accountThreePassword;
public final boolean debug;
public final Debugger debugger;
public final Set<String> enabledTests;
@ -84,7 +93,7 @@ public final class Configuration {
public final Set<String> testPackages;
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,
Set<String> testPackages, String adminAccountUsername, String adminAccountPassword)
throws KeyManagementException, NoSuchAlgorithmException {
@ -102,7 +111,7 @@ public final class Configuration {
} else {
this.replyTimeout = 60000;
}
this.debug = debug;
this.debugger = debugger;
if (StringUtils.isNotEmpty(adminAccountUsername, adminAccountPassword)) {
accountRegistration = AccountRegistration.serviceAdministration;
}
@ -162,7 +171,7 @@ public final class Configuration {
public String accountThreePassword;
private boolean debug;
private Debugger debugger = Debugger.none;
private Set<String> enabledTests;
@ -247,9 +256,27 @@ public final class Configuration {
return this;
}
public Builder setDebug(String debugString) {
if (debugString != null) {
debug = Boolean.valueOf(debugString);
@SuppressWarnings("fallthrough")
public Builder setDebugger(String debuggerString) {
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;
}
@ -291,7 +318,7 @@ public final class Configuration {
}
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,
testPackages, adminAccountUsername, adminAccountPassword);
}
@ -346,7 +373,12 @@ public final class Configuration {
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.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.NoResponseException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.debugger.ConsoleDebugger;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration.Builder;
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.igniterealtime.smack.inttest.IntTestUtil.UsernameAndPassword;
@ -98,6 +101,8 @@ public class SmackIntegrationTestFramework {
final int possibleTests = testRunResult.getNumberOfPossibleTests();
LOGGER.info("SmackIntegrationTestFramework[" + testRunResult.testRunId + ']' + ": Finished ["
+ successfulTests + '/' + possibleTests + "] (of " + availableTests + " available tests)");
int exitStatus;
if (!testRunResult.failedIntegrationTests.isEmpty()) {
final int failedTests = testRunResult.failedIntegrationTests.size();
LOGGER.warning("The following " + failedTests + " tests failed!");
@ -108,11 +113,21 @@ public class SmackIntegrationTestFramework {
final Throwable cause = failedTest.failureReason;
LOGGER.severe(className + CLASS_METHOD_SEP + methodName + " failed: " + cause);
}
System.exit(2);
exitStatus = 2;
} else {
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) {
@ -123,7 +138,7 @@ public class SmackIntegrationTestFramework {
IOException, XMPPException, InterruptedException {
testRunResult = new TestRunResult();
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
// level FINE
// TODO configure JUL for log?
@ -583,6 +598,19 @@ public class SmackIntegrationTestFramework {
}
builder.setSecurityMode(config.securityMode);
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());
connection.connect();
UsernameAndPassword uap = IntTestUtil.registerAccount(connection, environment, connectionId);

View file

@ -67,11 +67,11 @@ public class IoT {
final XMPPTCPConnectionConfiguration dataThingConnectionConfiguration = XMPPTCPConnectionConfiguration.builder()
.setUsernameAndPassword(dataThingJid.getLocalpart(), dataThingPassword)
.setXmppDomain(dataThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
.setDebuggerEnabled(true).build();
.enableDefaultDebugger().build();
final XMPPTCPConnectionConfiguration readingThingConnectionConfiguration = XMPPTCPConnectionConfiguration
.builder().setUsernameAndPassword(readingThingJid.getLocalpart(), readingThingPassword)
.setXmppDomain(readingThingJid.asDomainBareJid()).setSecurityMode(SecurityMode.disabled)
.setDebuggerEnabled(true).build();
.enableDefaultDebugger().build();
final XMPPTCPConnection dataThingConnection = new XMPPTCPConnection(dataThingConnectionConfiguration);
final XMPPTCPConnection readingThingConnection = new XMPPTCPConnection(readingThingConnectionConfiguration);

View file

@ -79,7 +79,9 @@ public class TlsTest {
.setPort(port)
.setSecurityMode(SecurityMode.required);
// @formatter:on
builder.setDebuggerEnabled(DEBUG);
if (DEBUG) {
builder.enableDefaultDebugger();
}
if (StringUtils.isNotEmpty(tlsPin)) {
SSLContext sslContext = Java7Pinning.forPin(tlsPin);

View file

@ -636,15 +636,6 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
if (isFirstInitialization) {
packetWriter = new PacketWriter();
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
packetWriter.init();