mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
Merge branch '4.2'
This commit is contained in:
commit
ca54f65b3e
346 changed files with 7037 additions and 5593 deletions
|
@ -4,7 +4,6 @@ android:
|
||||||
- android-8
|
- android-8
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- oraclejdk8
|
||||||
- oraclejdk7
|
|
||||||
sudo: false
|
sudo: false
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
|
|
|
@ -170,7 +170,7 @@ allprojects {
|
||||||
// version 52.0" error messages caused by the errorprone javac.
|
// version 52.0" error messages caused by the errorprone javac.
|
||||||
// See https://github.com/tbroyer/gradle-errorprone-plugin/issues/18 for more information.
|
// See https://github.com/tbroyer/gradle-errorprone-plugin/issues/18 for more information.
|
||||||
configurations.errorprone {
|
configurations.errorprone {
|
||||||
resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.5'
|
resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.15'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
<property name="format" value="^\s+$"/>
|
<property name="format" value="^\s+$"/>
|
||||||
<property name="message" value="Line containing only whitespace character(s)"/>
|
<property name="message" value="Line containing only whitespace character(s)"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="RegexpSingleline">
|
|
||||||
<property name="format" value="^ +\t+"/>
|
|
||||||
<property name="message" value="Line containing tab(s) after space"/>
|
|
||||||
</module>
|
|
||||||
<module name="RegexpSingleline">
|
<module name="RegexpSingleline">
|
||||||
<!-- We use {2,} instead of + here to address the typical case where a file was written
|
<!-- We use {2,} instead of + here to address the typical case where a file was written
|
||||||
with tabs but javadoc is causing '\t *' -->
|
with tabs but javadoc is causing '\t *' -->
|
||||||
|
@ -89,6 +85,10 @@
|
||||||
<property name="message" value="Usage of println"/>
|
<property name="message" value="Usage of println"/>
|
||||||
<property name="ignoreComments" value="true"/>
|
<property name="ignoreComments" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
|
<module name="RegexpSinglelineJava">
|
||||||
|
<property name="format" value="^\t+"/>
|
||||||
|
<property name="message" value="Indent must not use tab characters. Use space instead."/>
|
||||||
|
</module>
|
||||||
<module name="JavadocMethod">
|
<module name="JavadocMethod">
|
||||||
<!-- TODO stricten those checks -->
|
<!-- TODO stricten those checks -->
|
||||||
<property name="scope" value="public"/>
|
<property name="scope" value="public"/>
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -63,116 +63,116 @@ import android.os.SystemClock;
|
||||||
*/
|
*/
|
||||||
public final class ServerPingWithAlarmManager extends Manager {
|
public final class ServerPingWithAlarmManager extends Manager {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ServerPingWithAlarmManager.class
|
private static final Logger LOGGER = Logger.getLogger(ServerPingWithAlarmManager.class
|
||||||
.getName());
|
.getName());
|
||||||
|
|
||||||
private static final String PING_ALARM_ACTION = "org.igniterealtime.smackx.ping.ACTION";
|
private static final String PING_ALARM_ACTION = "org.igniterealtime.smackx.ping.ACTION";
|
||||||
|
|
||||||
private static final Map<XMPPConnection, ServerPingWithAlarmManager> INSTANCES = new WeakHashMap<XMPPConnection, ServerPingWithAlarmManager>();
|
private static final Map<XMPPConnection, ServerPingWithAlarmManager> INSTANCES = new WeakHashMap<XMPPConnection, ServerPingWithAlarmManager>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
@Override
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized ServerPingWithAlarmManager getInstanceFor(XMPPConnection connection) {
|
public static synchronized ServerPingWithAlarmManager getInstanceFor(XMPPConnection connection) {
|
||||||
ServerPingWithAlarmManager serverPingWithAlarmManager = INSTANCES.get(connection);
|
ServerPingWithAlarmManager serverPingWithAlarmManager = INSTANCES.get(connection);
|
||||||
if (serverPingWithAlarmManager == null) {
|
if (serverPingWithAlarmManager == null) {
|
||||||
serverPingWithAlarmManager = new ServerPingWithAlarmManager(connection);
|
serverPingWithAlarmManager = new ServerPingWithAlarmManager(connection);
|
||||||
INSTANCES.put(connection, serverPingWithAlarmManager);
|
INSTANCES.put(connection, serverPingWithAlarmManager);
|
||||||
}
|
}
|
||||||
return serverPingWithAlarmManager;
|
return serverPingWithAlarmManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean mEnabled = true;
|
private boolean mEnabled = true;
|
||||||
|
|
||||||
private ServerPingWithAlarmManager(XMPPConnection connection) {
|
private ServerPingWithAlarmManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If enabled, ServerPingWithAlarmManager will call {@link PingManager#pingServerIfNecessary()}
|
* If enabled, ServerPingWithAlarmManager will call {@link PingManager#pingServerIfNecessary()}
|
||||||
* for the connection of this instance every half hour.
|
* for the connection of this instance every half hour.
|
||||||
*
|
*
|
||||||
* @param enabled
|
* @param enabled
|
||||||
*/
|
*/
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
mEnabled = enabled;
|
mEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return mEnabled;
|
return mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() {
|
private static final BroadcastReceiver ALARM_BROADCAST_RECEIVER = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
LOGGER.fine("Ping Alarm broadcast received");
|
LOGGER.fine("Ping Alarm broadcast received");
|
||||||
Set<Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
|
Set<Entry<XMPPConnection, ServerPingWithAlarmManager>> managers;
|
||||||
synchronized (ServerPingWithAlarmManager.class) {
|
synchronized (ServerPingWithAlarmManager.class) {
|
||||||
// Make a copy to avoid ConcurrentModificationException when
|
// Make a copy to avoid ConcurrentModificationException when
|
||||||
// iterating directly over INSTANCES and the Set is modified
|
// iterating directly over INSTANCES and the Set is modified
|
||||||
// concurrently by creating a new ServerPingWithAlarmManager.
|
// concurrently by creating a new ServerPingWithAlarmManager.
|
||||||
managers = new HashSet<>(INSTANCES.entrySet());
|
managers = new HashSet<>(INSTANCES.entrySet());
|
||||||
}
|
}
|
||||||
for (Entry<XMPPConnection, ServerPingWithAlarmManager> entry : managers) {
|
for (Entry<XMPPConnection, ServerPingWithAlarmManager> entry : managers) {
|
||||||
XMPPConnection connection = entry.getKey();
|
XMPPConnection connection = entry.getKey();
|
||||||
if (entry.getValue().isEnabled()) {
|
if (entry.getValue().isEnabled()) {
|
||||||
LOGGER.fine("Calling pingServerIfNecessary for connection "
|
LOGGER.fine("Calling pingServerIfNecessary for connection "
|
||||||
+ connection);
|
+ connection);
|
||||||
final PingManager pingManager = PingManager.getInstanceFor(connection);
|
final PingManager pingManager = PingManager.getInstanceFor(connection);
|
||||||
// Android BroadcastReceivers have a timeout of 60 seconds.
|
// Android BroadcastReceivers have a timeout of 60 seconds.
|
||||||
// The connections reply timeout may be higher, which causes
|
// The connections reply timeout may be higher, which causes
|
||||||
// timeouts of the broadcast receiver and a subsequent ANR
|
// timeouts of the broadcast receiver and a subsequent ANR
|
||||||
// of the App of the broadcast receiver. We therefore need
|
// of the App of the broadcast receiver. We therefore need
|
||||||
// to call pingServerIfNecessary() in a new thread to avoid
|
// to call pingServerIfNecessary() in a new thread to avoid
|
||||||
// this. It could happen that the device gets back to sleep
|
// this. It could happen that the device gets back to sleep
|
||||||
// until the Thread runs, but that's a risk we are willing
|
// until the Thread runs, but that's a risk we are willing
|
||||||
// to take into account as it's unlikely.
|
// to take into account as it's unlikely.
|
||||||
Async.go(new Runnable() {
|
Async.go(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
pingManager.pingServerIfNecessary();
|
pingManager.pingServerIfNecessary();
|
||||||
}
|
}
|
||||||
}, "PingServerIfNecessary (" + connection.getConnectionCounter() + ')');
|
}, "PingServerIfNecessary (" + connection.getConnectionCounter() + ')');
|
||||||
} else {
|
} else {
|
||||||
LOGGER.fine("NOT calling pingServerIfNecessary (disabled) on connection "
|
LOGGER.fine("NOT calling pingServerIfNecessary (disabled) on connection "
|
||||||
+ connection.getConnectionCounter());
|
+ connection.getConnectionCounter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static Context sContext;
|
private static Context sContext;
|
||||||
private static PendingIntent sPendingIntent;
|
private static PendingIntent sPendingIntent;
|
||||||
private static AlarmManager sAlarmManager;
|
private static AlarmManager sAlarmManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a pending intent with the AlarmManager to be broadcasted every half hour and
|
* Register a pending intent with the AlarmManager to be broadcasted every half hour and
|
||||||
* register the alarm broadcast receiver to receive this intent. The receiver will check all
|
* register the alarm broadcast receiver to receive this intent. The receiver will check all
|
||||||
* known questions if a ping is Necessary when invoked by the alarm intent.
|
* known questions if a ping is Necessary when invoked by the alarm intent.
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context
|
||||||
*/
|
*/
|
||||||
public static void onCreate(Context context) {
|
public static void onCreate(Context context) {
|
||||||
sContext = context;
|
sContext = context;
|
||||||
context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION));
|
context.registerReceiver(ALARM_BROADCAST_RECEIVER, new IntentFilter(PING_ALARM_ACTION));
|
||||||
sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||||
sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), 0);
|
sPendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(PING_ALARM_ACTION), 0);
|
||||||
sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
sAlarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
||||||
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
|
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
|
||||||
AlarmManager.INTERVAL_HALF_HOUR, sPendingIntent);
|
AlarmManager.INTERVAL_HALF_HOUR, sPendingIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister the alarm broadcast receiver and cancel the alarm.
|
* Unregister the alarm broadcast receiver and cancel the alarm.
|
||||||
*/
|
*/
|
||||||
public static void onDestroy() {
|
public static void onDestroy() {
|
||||||
sContext.unregisterReceiver(ALARM_BROADCAST_RECEIVER);
|
sContext.unregisterReceiver(ALARM_BROADCAST_RECEIVER);
|
||||||
sAlarmManager.cancel(sPendingIntent);
|
sAlarmManager.cancel(sPendingIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -28,12 +28,12 @@ import org.jivesoftware.smack.util.stringencoder.android.AndroidBase64UrlSafeEnc
|
||||||
|
|
||||||
public class AndroidSmackInitializer implements SmackInitializer {
|
public class AndroidSmackInitializer implements SmackInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Exception> initialize() {
|
public List<Exception> initialize() {
|
||||||
SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier());
|
SmackConfiguration.setDefaultHostnameVerifier(new StrictHostnameVerifier());
|
||||||
Base64.setEncoder(AndroidBase64Encoder.getInstance());
|
Base64.setEncoder(AndroidBase64Encoder.getInstance());
|
||||||
Base64UrlSafeEncoder.setEncoder(AndroidBase64UrlSafeEncoder.getInstance());
|
Base64UrlSafeEncoder.setEncoder(AndroidBase64UrlSafeEncoder.getInstance());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ public final class BOSHConfiguration extends ConnectionConfiguration {
|
||||||
return proxy != null;
|
return proxy != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public ProxyInfo getProxyInfo() {
|
public ProxyInfo getProxyInfo() {
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,11 +203,13 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
saslFeatureReceived.reportSuccess();
|
saslFeatureReceived.reportSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isSecureConnection() {
|
public boolean isSecureConnection() {
|
||||||
// TODO: Implement SSL usage
|
// TODO: Implement SSL usage
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isUsingCompression() {
|
public boolean isUsingCompression() {
|
||||||
// TODO: Implement compression
|
// TODO: Implement compression
|
||||||
return false;
|
return false;
|
||||||
|
@ -313,16 +315,25 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
/**
|
/**
|
||||||
* Initialize the SmackDebugger which allows to log and debug XML traffic.
|
* Initialize the SmackDebugger which allows to log and debug XML traffic.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
protected void initDebugger() {
|
protected void initDebugger() {
|
||||||
// TODO: Maybe we want to extend the SmackDebugger for simplification
|
// TODO: Maybe we want to extend the SmackDebugger for simplification
|
||||||
// and a performance boost.
|
// and a performance boost.
|
||||||
|
|
||||||
// Initialize a empty writer which discards all data.
|
// Initialize a empty writer which discards all data.
|
||||||
writer = new Writer() {
|
writer = new Writer() {
|
||||||
public void write(char[] cbuf, int off, int len) { /* ignore */}
|
@Override
|
||||||
public void close() { /* ignore */ }
|
public void write(char[] cbuf, int off, int len) {
|
||||||
public void flush() { /* ignore */ }
|
/* ignore */}
|
||||||
};
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
/* ignore */ }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() {
|
||||||
|
/* ignore */ }
|
||||||
|
};
|
||||||
|
|
||||||
// Initialize a pipe for received raw data.
|
// Initialize a pipe for received raw data.
|
||||||
try {
|
try {
|
||||||
|
@ -338,6 +349,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
|
|
||||||
// Add listeners for the received and sent raw data.
|
// Add listeners for the received and sent raw data.
|
||||||
client.addBOSHClientResponseListener(new BOSHClientResponseListener() {
|
client.addBOSHClientResponseListener(new BOSHClientResponseListener() {
|
||||||
|
@Override
|
||||||
public void responseReceived(BOSHMessageEvent event) {
|
public void responseReceived(BOSHMessageEvent event) {
|
||||||
if (event.getBody() != null) {
|
if (event.getBody() != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -350,6 +362,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
client.addBOSHClientRequestListener(new BOSHClientRequestListener() {
|
client.addBOSHClientRequestListener(new BOSHClientRequestListener() {
|
||||||
|
@Override
|
||||||
public void requestSent(BOSHMessageEvent event) {
|
public void requestSent(BOSHMessageEvent event) {
|
||||||
if (event.getBody() != null) {
|
if (event.getBody() != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -366,6 +379,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
private Thread thread = this;
|
private Thread thread = this;
|
||||||
private int bufferLength = 1024;
|
private int bufferLength = 1024;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
char[] cbuf = new char[bufferLength];
|
char[] cbuf = new char[bufferLength];
|
||||||
|
@ -406,6 +420,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
* Process the connection listeners and try to login if the
|
* Process the connection listeners and try to login if the
|
||||||
* connection was formerly authenticated and is now reconnected.
|
* connection was formerly authenticated and is now reconnected.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void connectionEvent(BOSHClientConnEvent connEvent) {
|
public void connectionEvent(BOSHClientConnEvent connEvent) {
|
||||||
try {
|
try {
|
||||||
if (connEvent.isConnected()) {
|
if (connEvent.isConnected()) {
|
||||||
|
@ -463,6 +478,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @param event the BOSH client response which includes the received packet.
|
* @param event the BOSH client response which includes the received packet.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void responseReceived(BOSHMessageEvent event) {
|
public void responseReceived(BOSHMessageEvent event) {
|
||||||
AbstractBody body = event.getBody();
|
AbstractBody body = event.getBody();
|
||||||
if (body != null) {
|
if (body != null) {
|
||||||
|
|
|
@ -1494,6 +1494,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
final StanzaListener packetListener = new StanzaListener() {
|
final StanzaListener packetListener = new StanzaListener() {
|
||||||
@Override
|
@Override
|
||||||
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
|
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
|
||||||
|
boolean removed = removeAsyncStanzaListener(this);
|
||||||
|
if (!removed) {
|
||||||
|
// We lost a race against the "no response" handling runnable. Avoid calling the callback, as the
|
||||||
|
// exception callback will be invoked (if any).
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
XMPPErrorException.ifHasErrorThenThrow(packet);
|
XMPPErrorException.ifHasErrorThenThrow(packet);
|
||||||
callback.processStanza(packet);
|
callback.processStanza(packet);
|
||||||
|
@ -1503,9 +1509,6 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
exceptionCallback.processException(e);
|
exceptionCallback.processException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
removeAsyncStanzaListener(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
removeCallbacksService.schedule(new Runnable() {
|
removeCallbacksService.schedule(new Runnable() {
|
||||||
|
@ -1613,6 +1616,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
|
|
||||||
private long lastStanzaReceived;
|
private long lastStanzaReceived;
|
||||||
|
|
||||||
|
@Override
|
||||||
public long getLastStanzaReceived() {
|
public long getLastStanzaReceived() {
|
||||||
return lastStanzaReceived;
|
return lastStanzaReceived;
|
||||||
}
|
}
|
||||||
|
|
|
@ -576,14 +576,17 @@ public abstract class ConnectionConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the resource to use.
|
* Set the resource we are requesting from the server.
|
||||||
* <p>
|
* <p>
|
||||||
* If <code>resource</code> is <code>null</code>, then the server will automatically create a resource for the
|
* If <code>resource</code> is <code>null</code>, the default, then the server will automatically create a
|
||||||
* client. Default resource is "Smack".
|
* resource for the client. Note that XMPP clients only suggest this resource to the server. XMPP servers are
|
||||||
|
* allowed to ignore the client suggested resource and instead assign a completely different
|
||||||
|
* resource (see RFC 6120 § 7.7.1).
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param resource the resource to use.
|
* @param resource the resource to use.
|
||||||
* @return a reference to this builder.
|
* @return a reference to this builder.
|
||||||
|
* @see <a href="https://tools.ietf.org/html/rfc6120#section-7.7.1">RFC 6120 § 7.7.1</a>
|
||||||
*/
|
*/
|
||||||
public B setResource(Resourcepart resource) {
|
public B setResource(Resourcepart resource) {
|
||||||
this.resource = resource;
|
this.resource = resource;
|
||||||
|
@ -591,7 +594,7 @@ public abstract class ConnectionConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the resource to use.
|
* Set the resource we are requesting from the server.
|
||||||
*
|
*
|
||||||
* @param resource the non-null CharSequence to use a resource.
|
* @param resource the non-null CharSequence to use a resource.
|
||||||
* @return a reference ot this builder.
|
* @return a reference ot this builder.
|
||||||
|
|
|
@ -70,6 +70,7 @@ public final class ReconnectionManager {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
if (connection instanceof AbstractXMPPConnection) {
|
if (connection instanceof AbstractXMPPConnection) {
|
||||||
ReconnectionManager.getInstanceFor((AbstractXMPPConnection) connection);
|
ReconnectionManager.getInstanceFor((AbstractXMPPConnection) connection);
|
||||||
|
@ -204,6 +205,7 @@ public final class ReconnectionManager {
|
||||||
/**
|
/**
|
||||||
* The process will try the reconnection until the connection succeed or the user cancel it
|
* The process will try the reconnection until the connection succeed or the user cancel it
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final AbstractXMPPConnection connection = weakRefConnection.get();
|
final AbstractXMPPConnection connection = weakRefConnection.get();
|
||||||
if (connection == null) {
|
if (connection == null) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.jivesoftware.smack.sasl.core.SASLXOauth2Mechanism;
|
||||||
import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism;
|
import org.jivesoftware.smack.sasl.core.SCRAMSHA1Mechanism;
|
||||||
import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism;
|
import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism;
|
||||||
import org.jivesoftware.smack.util.FileUtils;
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlPullParserFactory;
|
import org.xmlpull.v1.XmlPullParserFactory;
|
||||||
|
@ -60,7 +61,7 @@ public final class SmackInitialization {
|
||||||
static {
|
static {
|
||||||
String smackVersion;
|
String smackVersion;
|
||||||
try {
|
try {
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtils.getStreamForUrl("classpath:org.jivesoftware.smack/version", null)));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(FileUtils.getStreamForUrl("classpath:org.jivesoftware.smack/version", null), StringUtils.UTF8));
|
||||||
smackVersion = reader.readLine();
|
smackVersion = reader.readLine();
|
||||||
try {
|
try {
|
||||||
reader.close();
|
reader.close();
|
||||||
|
@ -232,7 +233,7 @@ public final class SmackInitialization {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SmackInitializer.class.isAssignableFrom(initClass)) {
|
if (SmackInitializer.class.isAssignableFrom(initClass)) {
|
||||||
SmackInitializer initializer = (SmackInitializer) initClass.newInstance();
|
SmackInitializer initializer = (SmackInitializer) initClass.getConstructor().newInstance();
|
||||||
List<Exception> exceptions = initializer.initialize();
|
List<Exception> exceptions = initializer.initialize();
|
||||||
if (exceptions == null || exceptions.size() == 0) {
|
if (exceptions == null || exceptions.size() == 0) {
|
||||||
LOGGER.log(Level.FINE, "Loaded SmackInitializer " + className);
|
LOGGER.log(Level.FINE, "Loaded SmackInitializer " + className);
|
||||||
|
|
|
@ -49,6 +49,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
// 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);
|
||||||
readerListener = new ReaderListener() {
|
readerListener = new ReaderListener() {
|
||||||
|
@Override
|
||||||
public void read(String str) {
|
public void read(String str) {
|
||||||
log("RECV (" + connection.getConnectionCounter() + "): " + str);
|
log("RECV (" + connection.getConnectionCounter() + "): " + str);
|
||||||
}
|
}
|
||||||
|
@ -58,6 +59,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
||||||
this.writer = new ObservableWriter(writer);
|
this.writer = new ObservableWriter(writer);
|
||||||
writerListener = new WriterListener() {
|
writerListener = new WriterListener() {
|
||||||
|
@Override
|
||||||
public void write(String str) {
|
public void write(String str) {
|
||||||
log("SENT (" + connection.getConnectionCounter() + "): " + str);
|
log("SENT (" + connection.getConnectionCounter() + "): " + str);
|
||||||
}
|
}
|
||||||
|
@ -68,6 +70,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
// 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.
|
// data as Smack sees it and not as it's coming in as raw XML.
|
||||||
listener = new StanzaListener() {
|
listener = new StanzaListener() {
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
if (printInterpreted) {
|
if (printInterpreted) {
|
||||||
log("RCV PKT (" + connection.getConnectionCounter() + "): " + packet.toXML());
|
log("RCV PKT (" + connection.getConnectionCounter() + "): " + packet.toXML());
|
||||||
|
@ -76,10 +79,12 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
};
|
};
|
||||||
|
|
||||||
connListener = new ConnectionListener() {
|
connListener = new ConnectionListener() {
|
||||||
|
@Override
|
||||||
public void connected(XMPPConnection connection) {
|
public void connected(XMPPConnection connection) {
|
||||||
log("XMPPConnection connected ("
|
log("XMPPConnection connected ("
|
||||||
+ connection + ")");
|
+ connection + ")");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||||
String logString = "XMPPConnection authenticated (" + connection + ")";
|
String logString = "XMPPConnection authenticated (" + connection + ")";
|
||||||
if (resumed) {
|
if (resumed) {
|
||||||
|
@ -87,6 +92,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
log(logString);
|
log(logString);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void connectionClosed() {
|
public void connectionClosed() {
|
||||||
log(
|
log(
|
||||||
"XMPPConnection closed (" +
|
"XMPPConnection closed (" +
|
||||||
|
@ -94,24 +100,28 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
")");
|
")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void connectionClosedOnError(Exception e) {
|
public void connectionClosedOnError(Exception e) {
|
||||||
log(
|
log(
|
||||||
"XMPPConnection closed due to an exception (" +
|
"XMPPConnection closed due to an exception (" +
|
||||||
connection +
|
connection +
|
||||||
")", e);
|
")", e);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void reconnectionFailed(Exception e) {
|
public void reconnectionFailed(Exception e) {
|
||||||
log(
|
log(
|
||||||
"Reconnection failed due to an exception (" +
|
"Reconnection failed due to an exception (" +
|
||||||
connection +
|
connection +
|
||||||
")", e);
|
")", e);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void reconnectionSuccessful() {
|
public void reconnectionSuccessful() {
|
||||||
log(
|
log(
|
||||||
"XMPPConnection reconnected (" +
|
"XMPPConnection reconnected (" +
|
||||||
connection +
|
connection +
|
||||||
")");
|
")");
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void reconnectingIn(int seconds) {
|
public void reconnectingIn(int seconds) {
|
||||||
log(
|
log(
|
||||||
"XMPPConnection (" +
|
"XMPPConnection (" +
|
||||||
|
@ -125,6 +135,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
|
|
||||||
protected abstract void log(String logMessage, Throwable throwable);
|
protected abstract void log(String logMessage, Throwable throwable);
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader newConnectionReader(Reader newReader) {
|
public Reader newConnectionReader(Reader newReader) {
|
||||||
reader.removeReaderListener(readerListener);
|
reader.removeReaderListener(readerListener);
|
||||||
ObservableReader debugReader = new ObservableReader(newReader);
|
ObservableReader debugReader = new ObservableReader(newReader);
|
||||||
|
@ -133,6 +144,7 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer newConnectionWriter(Writer newWriter) {
|
public Writer newConnectionWriter(Writer newWriter) {
|
||||||
writer.removeWriterListener(writerListener);
|
writer.removeWriterListener(writerListener);
|
||||||
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
||||||
|
@ -159,18 +171,22 @@ public abstract class AbstractDebugger implements SmackDebugger {
|
||||||
connection.addConnectionListener(connListener);
|
connection.addConnectionListener(connListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader getReader() {
|
public Reader getReader() {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer getWriter() {
|
public Writer getWriter() {
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getReaderListener() {
|
public StanzaListener getReaderListener() {
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getWriterListener() {
|
public StanzaListener getWriterListener() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smack.filter;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
public abstract class AbstractFromToMatchesFilter implements StanzaFilter {
|
||||||
|
|
||||||
|
private final Jid address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag that indicates if the checking will be done against bare JID addresses or full JIDs.
|
||||||
|
*/
|
||||||
|
private final boolean ignoreResourcepart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a filter matching on the address returned by {@link #getAddressToCompare(Stanza)}. The address must be
|
||||||
|
* the same as the filter address. The second parameter specifies whether the full or the bare addresses are
|
||||||
|
* compared.
|
||||||
|
*
|
||||||
|
* @param address The address to filter for. If <code>null</code> is given, then
|
||||||
|
* {@link #getAddressToCompare(Stanza)} must also return <code>null</code> to match.
|
||||||
|
* @param ignoreResourcepart
|
||||||
|
*/
|
||||||
|
protected AbstractFromToMatchesFilter(Jid address, boolean ignoreResourcepart) {
|
||||||
|
if (address != null && ignoreResourcepart) {
|
||||||
|
this.address = address.asBareJid();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
this.ignoreResourcepart = ignoreResourcepart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean accept(final Stanza stanza) {
|
||||||
|
Jid stanzaAddress = getAddressToCompare(stanza);
|
||||||
|
|
||||||
|
if (stanzaAddress == null) {
|
||||||
|
return address == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreResourcepart) {
|
||||||
|
stanzaAddress = stanzaAddress.asBareJid();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stanzaAddress.equals(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract Jid getAddressToCompare(Stanza stanza);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final String toString() {
|
||||||
|
String matchMode = ignoreResourcepart ? "ignoreResourcepart" : "full";
|
||||||
|
return getClass().getSimpleName() + " (" + matchMode + "): " + address;
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ public class AndFilter extends AbstractListFilter implements StanzaFilter {
|
||||||
super(filters);
|
super(filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
for (StanzaFilter filter : filters) {
|
for (StanzaFilter filter : filters) {
|
||||||
if (!filter.accept(packet)) {
|
if (!filter.accept(packet)) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2014 Jive Software.
|
* Copyright 2003-2014 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.
|
||||||
|
@ -14,7 +14,6 @@
|
||||||
* 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.filter;
|
package org.jivesoftware.smack.filter;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
@ -28,14 +27,9 @@ import org.jxmpp.jid.Jid;
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
public class FromMatchesFilter implements StanzaFilter {
|
public final class FromMatchesFilter extends AbstractFromToMatchesFilter {
|
||||||
|
|
||||||
private final Jid address;
|
public final static FromMatchesFilter MATCH_NO_FROM_SET = create(null);
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag that indicates if the checking will be done against bare JID addresses or full JIDs.
|
|
||||||
*/
|
|
||||||
private final boolean ignoreResourcepart;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filter matching on the "from" field. The from address must be the same as the
|
* Creates a filter matching on the "from" field. The from address must be the same as the
|
||||||
|
@ -47,13 +41,7 @@ public class FromMatchesFilter implements StanzaFilter {
|
||||||
* @param ignoreResourcepart
|
* @param ignoreResourcepart
|
||||||
*/
|
*/
|
||||||
public FromMatchesFilter(Jid address, boolean ignoreResourcepart) {
|
public FromMatchesFilter(Jid address, boolean ignoreResourcepart) {
|
||||||
if (address != null && ignoreResourcepart) {
|
super(address, ignoreResourcepart);
|
||||||
this.address = address.asBareJid();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.address = address;
|
|
||||||
}
|
|
||||||
this.ignoreResourcepart = ignoreResourcepart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,51 +49,38 @@ public class FromMatchesFilter implements StanzaFilter {
|
||||||
* the filter address with the bare from address. Otherwise, compares the filter address
|
* the filter address with the bare from address. Otherwise, compares the filter address
|
||||||
* with the full from address.
|
* with the full from address.
|
||||||
*
|
*
|
||||||
* @param address The address to filter for. If <code>null</code> is given, the stanza(/packet) must not
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
* have a from address.
|
* have a from address.
|
||||||
*/
|
*/
|
||||||
public static FromMatchesFilter create(Jid address) {
|
public static FromMatchesFilter create(Jid address) {
|
||||||
return new FromMatchesFilter(address, address.hasNoResource()) ;
|
return new FromMatchesFilter(address, address != null ? address.hasNoResource() : false) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filter matching on the "from" field. Compares the bare version of from and filter
|
* Creates a filter matching on the "from" field. Compares the bare version of from and filter
|
||||||
* address.
|
* address.
|
||||||
*
|
*
|
||||||
* @param address The address to filter for. If <code>null</code> is given, the stanza(/packet) must not
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
* have a from address.
|
* have a from address.
|
||||||
*/
|
*/
|
||||||
public static FromMatchesFilter createBare(Jid address) {
|
public static FromMatchesFilter createBare(Jid address) {
|
||||||
address = (address == null) ? null : address;
|
|
||||||
return new FromMatchesFilter(address, true);
|
return new FromMatchesFilter(address, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filter matching on the "from" field. Compares the full version of from and filter
|
* Creates a filter matching on the "from" field. Compares the full version, if available, of from and filter
|
||||||
* address.
|
* address.
|
||||||
*
|
*
|
||||||
* @param address The address to filter for. If <code>null</code> is given, the stanza(/packet) must not
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
* have a from address.
|
* have a from address.
|
||||||
*/
|
*/
|
||||||
public static FromMatchesFilter createFull(Jid address) {
|
public static FromMatchesFilter createFull(Jid address) {
|
||||||
return new FromMatchesFilter(address, false);
|
return new FromMatchesFilter(address, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean accept(Stanza packet) {
|
@Override
|
||||||
Jid from = packet.getFrom();
|
protected Jid getAddressToCompare(Stanza stanza) {
|
||||||
if (from == null) {
|
return stanza.getFrom();
|
||||||
return address == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ignoreResourcepart) {
|
|
||||||
from = from.asBareJid();
|
|
||||||
}
|
|
||||||
return from.equals(address);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
String matchMode = ignoreResourcepart ? "ignoreResourcepart" : "full";
|
|
||||||
return getClass().getSimpleName() + " (" + matchMode + "): " + address;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,12 +35,12 @@ public final class IQTypeFilter extends FlexibleStanzaTypeFilter<IQ> {
|
||||||
public static final StanzaFilter ERROR = new IQTypeFilter(Type.error);
|
public static final StanzaFilter ERROR = new IQTypeFilter(Type.error);
|
||||||
public static final StanzaFilter GET_OR_SET = new OrFilter(GET, SET);
|
public static final StanzaFilter GET_OR_SET = new OrFilter(GET, SET);
|
||||||
|
|
||||||
private final IQ.Type type;
|
private final IQ.Type type;
|
||||||
|
|
||||||
private IQTypeFilter(IQ.Type type) {
|
private IQTypeFilter(IQ.Type type) {
|
||||||
super(IQ.class);
|
super(IQ.class);
|
||||||
this.type = Objects.requireNonNull(type, "Type must not be null");
|
this.type = Objects.requireNonNull(type, "Type must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean acceptSpecific(IQ iq) {
|
protected boolean acceptSpecific(IQ iq) {
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class NotFilter implements StanzaFilter {
|
||||||
this.filter = Objects.requireNonNull(filter, "Parameter must not be null.");
|
this.filter = Objects.requireNonNull(filter, "Parameter must not be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return !filter.accept(packet);
|
return !filter.accept(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ public class PacketExtensionFilter implements StanzaFilter {
|
||||||
this(packetExtension.getElementName(), packetExtension.getNamespace());
|
this(packetExtension.getElementName(), packetExtension.getNamespace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return packet.hasExtension(elementName, namespace);
|
return packet.hasExtension(elementName, namespace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,10 +54,12 @@ public class PacketIDFilter implements StanzaFilter {
|
||||||
this.packetID = packetID;
|
this.packetID = packetID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return packetID.equals(packet.getStanzaId());
|
return packetID.equals(packet.getStanzaId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + ": id=" + packetID;
|
return getClass().getSimpleName() + ": id=" + packetID;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class PacketTypeFilter implements StanzaFilter {
|
||||||
this.packetType = packetType;
|
this.packetType = packetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return packetType.isInstance(packet);
|
return packetType.isInstance(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ public class StanzaExtensionFilter implements StanzaFilter {
|
||||||
this(packetExtension.getElementName(), packetExtension.getNamespace());
|
this(packetExtension.getElementName(), packetExtension.getNamespace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return packet.hasExtension(elementName, namespace);
|
return packet.hasExtension(elementName, namespace);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,10 +47,12 @@ public class StanzaIdFilter implements StanzaFilter {
|
||||||
this.stanzaId = StringUtils.requireNotNullOrEmpty(stanzaID, "Stanza ID must not be null or empty.");
|
this.stanzaId = StringUtils.requireNotNullOrEmpty(stanzaID, "Stanza ID must not be null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza stanza) {
|
public boolean accept(Stanza stanza) {
|
||||||
return stanzaId.equals(stanza.getStanzaId());
|
return stanzaId.equals(stanza.getStanzaId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + ": id=" + stanzaId;
|
return getClass().getSimpleName() + ": id=" + stanzaId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public final class StanzaTypeFilter implements StanzaFilter {
|
||||||
this.packetType = packetType;
|
this.packetType = packetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
return packetType.isInstance(packet);
|
return packetType.isInstance(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,12 @@ package org.jivesoftware.smack.filter;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match based on the 'to' attribute of a Stanza.
|
||||||
|
*
|
||||||
|
* @deprecated use {@link ToMatchesFilter} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public class ToFilter implements StanzaFilter {
|
public class ToFilter implements StanzaFilter {
|
||||||
|
|
||||||
private final Jid to;
|
private final Jid to;
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smack.filter;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
public final class ToMatchesFilter extends AbstractFromToMatchesFilter {
|
||||||
|
|
||||||
|
public static final ToMatchesFilter MATCH_NO_TO_SET = create(null);
|
||||||
|
|
||||||
|
public ToMatchesFilter(Jid address, boolean ignoreResourcepart) {
|
||||||
|
super(address, ignoreResourcepart);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a filter matching on the "to" field. If the filter address is bare, compares
|
||||||
|
* the filter address with the bare from address. Otherwise, compares the filter address
|
||||||
|
* with the full from address.
|
||||||
|
*
|
||||||
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
|
* have a from address.
|
||||||
|
*/
|
||||||
|
public static ToMatchesFilter create(Jid address) {
|
||||||
|
return new ToMatchesFilter(address, address != null ? address.hasNoResource() : false) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a filter matching on the "to" field. Compares the bare version of to and filter
|
||||||
|
* address.
|
||||||
|
*
|
||||||
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
|
* have a from address.
|
||||||
|
*/
|
||||||
|
public static ToMatchesFilter createBare(Jid address) {
|
||||||
|
return new ToMatchesFilter(address, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a filter matching on the "to" field. Compares the full version, if available, of to and filter
|
||||||
|
* address.
|
||||||
|
*
|
||||||
|
* @param address The address to filter for. If <code>null</code> is given, the stanza must not
|
||||||
|
* have a from address.
|
||||||
|
*/
|
||||||
|
public static ToMatchesFilter createFull(Jid address) {
|
||||||
|
return new ToMatchesFilter(address, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Jid getAddressToCompare(Stanza stanza) {
|
||||||
|
return stanza.getTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -70,6 +70,7 @@ public class DefaultExtensionElement implements ExtensionElement {
|
||||||
*
|
*
|
||||||
* @return the XML element name of the stanza(/packet) extension.
|
* @return the XML element name of the stanza(/packet) extension.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return elementName;
|
return elementName;
|
||||||
}
|
}
|
||||||
|
@ -79,6 +80,7 @@ public class DefaultExtensionElement implements ExtensionElement {
|
||||||
*
|
*
|
||||||
* @return the XML namespace of the stanza(/packet) extension.
|
* @return the XML namespace of the stanza(/packet) extension.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return namespace;
|
return namespace;
|
||||||
}
|
}
|
||||||
|
|
|
@ -570,6 +570,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
|
@ -578,6 +579,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -632,6 +634,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int prime = 31;
|
final int prime = 31;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
|
@ -640,6 +643,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -78,7 +78,7 @@ public class IntrospectionProvider{
|
||||||
IOException, IllegalArgumentException, InvocationTargetException,
|
IOException, IllegalArgumentException, InvocationTargetException,
|
||||||
ClassNotFoundException {
|
ClassNotFoundException {
|
||||||
ParserUtils.assertAtStartTag(parser);
|
ParserUtils.assertAtStartTag(parser);
|
||||||
Object object = objectClass.newInstance();
|
Object object = objectClass.getConstructor().newInstance();
|
||||||
outerloop: while (true) {
|
outerloop: while (true) {
|
||||||
int eventType = parser.next();
|
int eventType = parser.next();
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
|
|
|
@ -83,7 +83,8 @@ public class ProviderFileLoader implements ProviderLoader {
|
||||||
// reflection later to create instances of the class.
|
// reflection later to create instances of the class.
|
||||||
// Add the provider to the map.
|
// Add the provider to the map.
|
||||||
if (IQProvider.class.isAssignableFrom(provider)) {
|
if (IQProvider.class.isAssignableFrom(provider)) {
|
||||||
iqProviders.add(new IQProviderInfo(elementName, namespace, (IQProvider<IQ>) provider.newInstance()));
|
IQProvider<IQ> iqProvider = (IQProvider<IQ>) provider.getConstructor().newInstance();
|
||||||
|
iqProviders.add(new IQProviderInfo(elementName, namespace, iqProvider));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exceptions.add(new IllegalArgumentException(className + " is not a IQProvider"));
|
exceptions.add(new IllegalArgumentException(className + " is not a IQProvider"));
|
||||||
|
@ -96,7 +97,9 @@ public class ProviderFileLoader implements ProviderLoader {
|
||||||
// then we'll use reflection later to create instances
|
// then we'll use reflection later to create instances
|
||||||
// of the class.
|
// of the class.
|
||||||
if (ExtensionElementProvider.class.isAssignableFrom(provider)) {
|
if (ExtensionElementProvider.class.isAssignableFrom(provider)) {
|
||||||
extProviders.add(new ExtensionProviderInfo(elementName, namespace, (ExtensionElementProvider<ExtensionElement>) provider.newInstance()));
|
ExtensionElementProvider<ExtensionElement> extensionElementProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
|
||||||
|
extProviders.add(new ExtensionProviderInfo(elementName, namespace,
|
||||||
|
extensionElementProvider));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exceptions.add(new IllegalArgumentException(className
|
exceptions.add(new IllegalArgumentException(className
|
||||||
|
@ -104,9 +107,10 @@ public class ProviderFileLoader implements ProviderLoader {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "streamFeatureProvider":
|
case "streamFeatureProvider":
|
||||||
|
ExtensionElementProvider<ExtensionElement> streamFeatureProvider = (ExtensionElementProvider<ExtensionElement>) provider.getConstructor().newInstance();
|
||||||
sfProviders.add(new StreamFeatureProviderInfo(elementName,
|
sfProviders.add(new StreamFeatureProviderInfo(elementName,
|
||||||
namespace,
|
namespace,
|
||||||
(ExtensionElementProvider<ExtensionElement>) provider.newInstance()));
|
streamFeatureProvider));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGGER.warning("Unknown provider type: " + typeName);
|
LOGGER.warning("Unknown provider type: " + typeName);
|
||||||
|
|
|
@ -23,6 +23,8 @@ import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Socket factory for socks4 proxy.
|
* Socket factory for socks4 proxy.
|
||||||
*
|
*
|
||||||
|
@ -89,7 +91,8 @@ public class Socks4ProxySocketConnection implements ProxySocketConnection {
|
||||||
|
|
||||||
if(user!=null)
|
if(user!=null)
|
||||||
{
|
{
|
||||||
System.arraycopy(user.getBytes(), 0, buf, index, user.length());
|
byte[] userBytes = user.getBytes(StringUtils.UTF8);
|
||||||
|
System.arraycopy(userBytes, 0, buf, index, user.length());
|
||||||
index+=user.length();
|
index+=user.length();
|
||||||
}
|
}
|
||||||
buf[index++]=0;
|
buf[index++]=0;
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.io.OutputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Socket factory for Socks5 proxy.
|
* Socket factory for Socks5 proxy.
|
||||||
*
|
*
|
||||||
|
@ -132,11 +134,13 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
|
||||||
index=0;
|
index=0;
|
||||||
buf[index++]=1;
|
buf[index++]=1;
|
||||||
buf[index++]=(byte)(user.length());
|
buf[index++]=(byte)(user.length());
|
||||||
System.arraycopy(user.getBytes(), 0, buf, index,
|
byte[] userBytes = user.getBytes(StringUtils.UTF8);
|
||||||
|
System.arraycopy(userBytes, 0, buf, index,
|
||||||
user.length());
|
user.length());
|
||||||
index+=user.length();
|
index+=user.length();
|
||||||
buf[index++]=(byte)(passwd.length());
|
byte[] passwordBytes = user.getBytes(StringUtils.UTF8);
|
||||||
System.arraycopy(passwd.getBytes(), 0, buf, index,
|
buf[index++]=(byte)(passwordBytes.length);
|
||||||
|
System.arraycopy(passwordBytes, 0, buf, index,
|
||||||
passwd.length());
|
passwd.length());
|
||||||
index+=passwd.length();
|
index+=passwd.length();
|
||||||
|
|
||||||
|
@ -210,7 +214,7 @@ public class Socks5ProxySocketConnection implements ProxySocketConnection {
|
||||||
buf[index++]=1; // CONNECT
|
buf[index++]=1; // CONNECT
|
||||||
buf[index++]=0;
|
buf[index++]=0;
|
||||||
|
|
||||||
byte[] hostb= host.getBytes();
|
byte[] hostb= host.getBytes(StringUtils.UTF8);
|
||||||
int len=hostb.length;
|
int len=hostb.length;
|
||||||
buf[index++]=3; // DOMAINNAME
|
buf[index++]=3; // DOMAINNAME
|
||||||
buf[index++]=(byte)(len);
|
buf[index++]=(byte)(len);
|
||||||
|
|
|
@ -265,8 +265,11 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final int compareTo(SASLMechanism other) {
|
public final int compareTo(SASLMechanism other) {
|
||||||
return getPriority() - other.getPriority();
|
// Switch to Integer.compare(int, int) once Smack is on Android 19 or higher.
|
||||||
|
Integer ourPriority = getPriority();
|
||||||
|
return ourPriority.compareTo(other.getPriority());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -298,7 +301,7 @@ public abstract class SASLMechanism implements Comparable<SASLMechanism> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SASLprep the given String.
|
* SASLprep the given String. The resulting String is in UTF-8.
|
||||||
*
|
*
|
||||||
* @param string the String to sasl prep.
|
* @param string the String to sasl prep.
|
||||||
* @return the given String SASL preped
|
* @return the given String SASL preped
|
||||||
|
|
|
@ -30,6 +30,7 @@ public class SASLAnonymous extends SASLMechanism {
|
||||||
|
|
||||||
public static final String NAME = "ANONYMOUS";
|
public static final String NAME = "ANONYMOUS";
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return NAME;
|
return NAME;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack.sasl.core;
|
package org.jivesoftware.smack.sasl.core;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -105,7 +106,15 @@ public abstract class ScramMechanism extends SASLMechanism {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected byte[] evaluateChallenge(byte[] challenge) throws SmackException {
|
protected byte[] evaluateChallenge(byte[] challenge) throws SmackException {
|
||||||
final String challengeString = new String(challenge);
|
String challengeString;
|
||||||
|
try {
|
||||||
|
// TODO: Where is it specified that this is an UTF-8 encoded string?
|
||||||
|
challengeString = new String(challenge, StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case AUTH_TEXT_SENT:
|
case AUTH_TEXT_SENT:
|
||||||
final String serverFirstMessage = challengeString;
|
final String serverFirstMessage = challengeString;
|
||||||
|
@ -358,14 +367,21 @@ public abstract class ScramMechanism extends SASLMechanism {
|
||||||
* (PRF) and with dkLen == output length of HMAC() == output length of H().
|
* (PRF) and with dkLen == output length of HMAC() == output length of H().
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param str
|
* @param normalizedPassword the normalized password.
|
||||||
* @param salt
|
* @param salt
|
||||||
* @param iterations
|
* @param iterations
|
||||||
* @return the result of the Hi function.
|
* @return the result of the Hi function.
|
||||||
* @throws SmackException
|
* @throws SmackException
|
||||||
*/
|
*/
|
||||||
private byte[] hi(String str, byte[] salt, int iterations) throws SmackException {
|
private byte[] hi(String normalizedPassword, byte[] salt, int iterations) throws SmackException {
|
||||||
byte[] key = str.getBytes();
|
byte[] key;
|
||||||
|
try {
|
||||||
|
// According to RFC 5802 § 2.2, the resulting string of the normalization is also in UTF-8.
|
||||||
|
key = normalizedPassword.getBytes(StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
// U1 := HMAC(str, salt + INT(1))
|
// U1 := HMAC(str, salt + INT(1))
|
||||||
byte[] u = hmac(key, ByteUtils.concact(salt, ONE));
|
byte[] u = hmac(key, ByteUtils.concact(salt, ONE));
|
||||||
byte[] res = u.clone();
|
byte[] res = u.clone();
|
||||||
|
|
|
@ -240,6 +240,7 @@ public class ArrayBlockingQueueWithShutdown<E> extends AbstractQueue<E> implemen
|
||||||
* @param e the element to add.
|
* @param e the element to add.
|
||||||
* @throws InterruptedException if interrupted while waiting or if the queue was shut down.
|
* @throws InterruptedException if interrupted while waiting or if the queue was shut down.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void put(E e) throws InterruptedException {
|
public void put(E e) throws InterruptedException {
|
||||||
checkNotNull(e);
|
checkNotNull(e);
|
||||||
lock.lockInterruptibly();
|
lock.lockInterruptibly();
|
||||||
|
@ -452,6 +453,7 @@ public class ArrayBlockingQueueWithShutdown<E> extends AbstractQueue<E> implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
return nextIndex >= 0;
|
return nextIndex >= 0;
|
||||||
}
|
}
|
||||||
|
@ -469,6 +471,7 @@ public class ArrayBlockingQueueWithShutdown<E> extends AbstractQueue<E> implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public E next() {
|
public E next() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
@ -486,6 +489,7 @@ public class ArrayBlockingQueueWithShutdown<E> extends AbstractQueue<E> implemen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -185,7 +185,7 @@ public class DNSUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain, failedAddresses, dnssecMode);
|
List<SRVRecord> srvRecords = dnsResolver.lookupSRVRecords(srvDomain, failedAddresses, dnssecMode);
|
||||||
if (srvRecords != null) {
|
if (srvRecords != null && !srvRecords.isEmpty()) {
|
||||||
if (LOGGER.isLoggable(Level.FINE)) {
|
if (LOGGER.isLoggable(Level.FINE)) {
|
||||||
String logMessage = "Resolved SRV RR for " + srvDomain + ":";
|
String logMessage = "Resolved SRV RR for " + srvDomain + ":";
|
||||||
for (SRVRecord r : srvRecords)
|
for (SRVRecord r : srvRecords)
|
||||||
|
@ -194,6 +194,8 @@ public class DNSUtil {
|
||||||
}
|
}
|
||||||
List<HostAddress> sortedRecords = sortSRVRecords(srvRecords);
|
List<HostAddress> sortedRecords = sortSRVRecords(srvRecords);
|
||||||
addresses.addAll(sortedRecords);
|
addresses.addAll(sortedRecords);
|
||||||
|
} else {
|
||||||
|
LOGGER.info("Could not resolve DNS SRV resource records for " + srvDomain + ". Consider adding those.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int defaultPort = -1;
|
int defaultPort = -1;
|
||||||
|
|
|
@ -87,7 +87,8 @@ public final class FileUtils {
|
||||||
public static boolean addLines(String url, Set<String> set) throws MalformedURLException, IOException {
|
public static boolean addLines(String url, Set<String> set) throws MalformedURLException, IOException {
|
||||||
InputStream is = getStreamForUrl(url, null);
|
InputStream is = getStreamForUrl(url, null);
|
||||||
if (is == null) return false;
|
if (is == null) return false;
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
InputStreamReader sr = new InputStreamReader(is, StringUtils.UTF8);
|
||||||
|
BufferedReader br = new BufferedReader(sr);
|
||||||
String line;
|
String line;
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
set.add(line);
|
set.add(line);
|
||||||
|
@ -102,6 +103,7 @@ public final class FileUtils {
|
||||||
* @return the content of file or null in case of an error
|
* @return the content of file or null in case of an error
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("DefaultCharset")
|
||||||
public static String readFileOrThrow(File file) throws FileNotFoundException, IOException {
|
public static String readFileOrThrow(File file) throws FileNotFoundException, IOException {
|
||||||
Reader reader = null;
|
Reader reader = null;
|
||||||
try {
|
try {
|
||||||
|
@ -132,6 +134,7 @@ public final class FileUtils {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("DefaultCharset")
|
||||||
public static void writeFileOrThrow(File file, CharSequence content) throws IOException {
|
public static void writeFileOrThrow(File file, CharSequence content) throws IOException {
|
||||||
FileWriter writer = new FileWriter(file, false);
|
FileWriter writer = new FileWriter(file, false);
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -37,6 +37,7 @@ public class ObservableReader extends Reader {
|
||||||
this.wrappedReader = wrappedReader;
|
this.wrappedReader = wrappedReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||||
int count = wrappedReader.read(cbuf, off, len);
|
int count = wrappedReader.read(cbuf, off, len);
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
@ -54,34 +55,42 @@ public class ObservableReader extends Reader {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
wrappedReader.close();
|
wrappedReader.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
return wrappedReader.read();
|
return wrappedReader.read();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int read(char[] cbuf) throws IOException {
|
public int read(char[] cbuf) throws IOException {
|
||||||
return wrappedReader.read(cbuf);
|
return wrappedReader.read(cbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public long skip(long n) throws IOException {
|
public long skip(long n) throws IOException {
|
||||||
return wrappedReader.skip(n);
|
return wrappedReader.skip(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean ready() throws IOException {
|
public boolean ready() throws IOException {
|
||||||
return wrappedReader.ready();
|
return wrappedReader.ready();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean markSupported() {
|
public boolean markSupported() {
|
||||||
return wrappedReader.markSupported();
|
return wrappedReader.markSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mark(int readAheadLimit) throws IOException {
|
public void mark(int readAheadLimit) throws IOException {
|
||||||
wrappedReader.mark(readAheadLimit);
|
wrappedReader.mark(readAheadLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reset() throws IOException {
|
public void reset() throws IOException {
|
||||||
wrappedReader.reset();
|
wrappedReader.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,36 +38,43 @@ public class ObservableWriter extends Writer {
|
||||||
this.wrappedWriter = wrappedWriter;
|
this.wrappedWriter = wrappedWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(char[] cbuf, int off, int len) throws IOException {
|
public void write(char[] cbuf, int off, int len) throws IOException {
|
||||||
wrappedWriter.write(cbuf, off, len);
|
wrappedWriter.write(cbuf, off, len);
|
||||||
String str = new String(cbuf, off, len);
|
String str = new String(cbuf, off, len);
|
||||||
maybeNotifyListeners(str);
|
maybeNotifyListeners(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
wrappedWriter.flush();
|
wrappedWriter.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
wrappedWriter.close();
|
wrappedWriter.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(int c) throws IOException {
|
public void write(int c) throws IOException {
|
||||||
wrappedWriter.write(c);
|
wrappedWriter.write(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(char[] cbuf) throws IOException {
|
public void write(char[] cbuf) throws IOException {
|
||||||
wrappedWriter.write(cbuf);
|
wrappedWriter.write(cbuf);
|
||||||
String str = new String(cbuf);
|
String str = new String(cbuf);
|
||||||
maybeNotifyListeners(str);
|
maybeNotifyListeners(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(String str) throws IOException {
|
public void write(String str) throws IOException {
|
||||||
wrappedWriter.write(str);
|
wrappedWriter.write(str);
|
||||||
maybeNotifyListeners(str);
|
maybeNotifyListeners(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(String str, int off, int len) throws IOException {
|
public void write(String str, int off, int len) throws IOException {
|
||||||
wrappedWriter.write(str, off, len);
|
wrappedWriter.write(str, off, len);
|
||||||
str = str.substring(off, off + len);
|
str = str.substring(off, off + len);
|
||||||
|
|
|
@ -290,8 +290,6 @@ public class PacketParserUtils {
|
||||||
break outerloop;
|
break outerloop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.TEXT:
|
|
||||||
throw new IllegalStateException("Invalid Stanza: Must not contain text or mixed content as direct child of <message/>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,8 +590,6 @@ public class PacketParserUtils {
|
||||||
break outerloop;
|
break outerloop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.TEXT:
|
|
||||||
throw new IllegalStateException("Invalid Stanza: Must not contain text or mixed content as direct child of <presence/>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return presence;
|
return presence;
|
||||||
|
@ -650,8 +646,6 @@ public class PacketParserUtils {
|
||||||
break outerloop;
|
break outerloop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case XmlPullParser.TEXT:
|
|
||||||
throw new IllegalStateException("Invalid Stanza: Must not contain text or mixed content as direct child of <iq/>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Decide what to do when an IQ packet was not understood
|
// Decide what to do when an IQ packet was not understood
|
||||||
|
|
|
@ -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.
|
||||||
|
@ -26,6 +26,7 @@ import java.util.Locale;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.EntityFullJid;
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
import org.jxmpp.jid.EntityJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.jid.parts.Resourcepart;
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
@ -98,6 +99,24 @@ public class ParserUtils {
|
||||||
return JidCreate.entityFullFrom(jidString);
|
return JidCreate.entityFullFrom(jidString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EntityJid getEntityJidAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
|
||||||
|
final String jidString = parser.getAttributeValue("", name);
|
||||||
|
if (jidString == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Jid jid = JidCreate.from(jidString);
|
||||||
|
|
||||||
|
if (!jid.hasLocalpart()) return null;
|
||||||
|
|
||||||
|
EntityFullJid fullJid = jid.asEntityFullJidIfPossible();
|
||||||
|
if (fullJid != null) {
|
||||||
|
return fullJid;
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityBareJid bareJid = jid.asEntityBareJidIfPossible();
|
||||||
|
return bareJid;
|
||||||
|
}
|
||||||
|
|
||||||
public static Resourcepart getResourcepartAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
|
public static Resourcepart getResourcepartAttribute(XmlPullParser parser, String name) throws XmppStringprepException {
|
||||||
final String resourcepartString = parser.getAttributeValue("", name);
|
final String resourcepartString = parser.getAttributeValue("", name);
|
||||||
if (resourcepartString == null) {
|
if (resourcepartString == null) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
||||||
|
|
||||||
|
@ -29,6 +30,8 @@ import org.jivesoftware.smack.ConnectionConfiguration.DnssecMode;
|
||||||
*/
|
*/
|
||||||
public abstract class DNSResolver {
|
public abstract class DNSResolver {
|
||||||
|
|
||||||
|
protected static final Logger LOGGER = Logger.getLogger(DNSResolver.class.getName());
|
||||||
|
|
||||||
private final boolean supportsDnssec;
|
private final boolean supportsDnssec;
|
||||||
|
|
||||||
protected DNSResolver(boolean supportsDnssec) {
|
protected DNSResolver(boolean supportsDnssec) {
|
||||||
|
|
|
@ -20,6 +20,9 @@ package org.jivesoftware.smack.util.stringencoder;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base32 string encoding is useful for when filenames case-insensitive filesystems are encoded.
|
* Base32 string encoding is useful for when filenames case-insensitive filesystems are encoded.
|
||||||
|
@ -53,7 +56,13 @@ public class Base32 {
|
||||||
|
|
||||||
public static String decode(String str) {
|
public static String decode(String str) {
|
||||||
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
ByteArrayOutputStream bs = new ByteArrayOutputStream();
|
||||||
byte[] raw = str.getBytes();
|
byte[] raw;
|
||||||
|
try {
|
||||||
|
raw = str.getBytes(StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
for (int i = 0; i < raw.length; i++) {
|
for (int i = 0; i < raw.length; i++) {
|
||||||
char c = (char) raw[i];
|
char c = (char) raw[i];
|
||||||
if (!Character.isWhitespace(c)) {
|
if (!Character.isWhitespace(c)) {
|
||||||
|
@ -106,11 +115,24 @@ public class Base32 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String(bs.toByteArray());
|
String res;
|
||||||
|
try {
|
||||||
|
res = new String(bs.toByteArray(), StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String encode(String str) {
|
public static String encode(String str) {
|
||||||
byte[] b = str.getBytes();
|
byte[] b;
|
||||||
|
try {
|
||||||
|
b = str.getBytes(StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||||
|
|
||||||
for (int i = 0; i < (b.length + 4) / 5; i++) {
|
for (int i = 0; i < (b.length + 4) / 5; i++) {
|
||||||
|
@ -153,7 +175,14 @@ public class Base32 {
|
||||||
os.write(c);
|
os.write(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new String(os.toByteArray());
|
String res;
|
||||||
|
try {
|
||||||
|
res = new String(os.toByteArray(), StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int lenToPadding(int blocklen) {
|
private static int lenToPadding(int blocklen) {
|
||||||
|
|
|
@ -180,6 +180,7 @@ public class DummyConnection extends AbstractXMPPConnection {
|
||||||
*
|
*
|
||||||
* @param packet the stanza(/packet) to process.
|
* @param packet the stanza(/packet) to process.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
invokeStanzaCollectorsAndNotifyRecvListeners(packet);
|
invokeStanzaCollectorsAndNotifyRecvListeners(packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,190 +26,190 @@ import org.junit.Test;
|
||||||
public class StanzaCollectorTest
|
public class StanzaCollectorTest
|
||||||
{
|
{
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyRollover() throws InterruptedException
|
public void verifyRollover() throws InterruptedException
|
||||||
{
|
{
|
||||||
TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), 5);
|
TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), 5);
|
||||||
|
|
||||||
for (int i=0; i<6; i++)
|
for (int i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
Stanza testPacket = new TestPacket(i);
|
Stanza testPacket = new TestPacket(i);
|
||||||
collector.processStanza(testPacket);
|
collector.processStanza(testPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assert that '0' has rolled off
|
// Assert that '0' has rolled off
|
||||||
assertEquals("1", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("1", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("2", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("2", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("3", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("3", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("4", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("4", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("5", collector.pollResult().getStanzaId());
|
assertEquals("5", collector.pollResult().getStanzaId());
|
||||||
assertNull(collector.pollResult());
|
assertNull(collector.pollResult());
|
||||||
|
|
||||||
for (int i=10; i<15; i++)
|
for (int i=10; i<15; i++)
|
||||||
{
|
{
|
||||||
Stanza testPacket = new TestPacket(i);
|
Stanza testPacket = new TestPacket(i);
|
||||||
collector.processStanza(testPacket);
|
collector.processStanza(testPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("10", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("10", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("11", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("11", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("12", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("12", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("13", collector.nextResultBlockForever().getStanzaId());
|
assertEquals("13", collector.nextResultBlockForever().getStanzaId());
|
||||||
assertEquals("14", collector.pollResult().getStanzaId());
|
assertEquals("14", collector.pollResult().getStanzaId());
|
||||||
assertNull(collector.pollResult());
|
assertNull(collector.pollResult());
|
||||||
|
|
||||||
assertNull(collector.nextResult(1000));
|
assertNull(collector.nextResult(1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Although this doesn't guarentee anything due to the nature of threading, it can potentially
|
* Although this doesn't guarentee anything due to the nature of threading, it can potentially
|
||||||
* catch problems.
|
* catch problems.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void verifyThreadSafety()
|
public void verifyThreadSafety()
|
||||||
{
|
{
|
||||||
int insertCount = 500;
|
int insertCount = 500;
|
||||||
final TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), insertCount);
|
final TestStanzaCollector collector = new TestStanzaCollector(null, new OKEverything(), insertCount);
|
||||||
|
|
||||||
Thread consumer1 = new Thread(new Runnable()
|
Thread consumer1 = new Thread(new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(3);
|
Thread.sleep(3);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
Stanza packet = collector.nextResultBlockForever();
|
Stanza packet = collector.nextResultBlockForever();
|
||||||
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
// System.out.println(Thread.currentThread().getName() + " packet: " + packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
consumer1.setName("consumer 1");
|
consumer1.setName("consumer 1");
|
||||||
|
|
||||||
Thread consumer2 = new Thread(new Runnable()
|
Thread consumer2 = new Thread(new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
Stanza p = null;
|
Stanza p = null;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(3);
|
Thread.sleep(3);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
p = collector.nextResult(1);
|
p = collector.nextResult(1);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||||
}
|
}
|
||||||
while (p != null);
|
while (p != null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
consumer2.setName("consumer 2");
|
consumer2.setName("consumer 2");
|
||||||
|
|
||||||
Thread consumer3 = new Thread(new Runnable()
|
Thread consumer3 = new Thread(new Runnable()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
Stanza p = null;
|
Stanza p = null;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(3);
|
Thread.sleep(3);
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
p = collector.pollResult();
|
p = collector.pollResult();
|
||||||
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
// System.out.println(Thread.currentThread().getName() + " packet: " + p);
|
||||||
}
|
}
|
||||||
while (p != null);
|
while (p != null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
consumer3.setName("consumer 3");
|
consumer3.setName("consumer 3");
|
||||||
|
|
||||||
consumer1.start();
|
consumer1.start();
|
||||||
consumer2.start();
|
consumer2.start();
|
||||||
consumer3.start();
|
consumer3.start();
|
||||||
|
|
||||||
for(int i=0; i<insertCount; i++)
|
for(int i=0; i<insertCount; i++)
|
||||||
{
|
{
|
||||||
collector.processStanza(new TestPacket(i));
|
collector.processStanza(new TestPacket(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(5000);
|
Thread.sleep(5000);
|
||||||
consumer3.join();
|
consumer3.join();
|
||||||
consumer2.join();
|
consumer2.join();
|
||||||
consumer1.interrupt();
|
consumer1.interrupt();
|
||||||
}
|
}
|
||||||
catch (InterruptedException e)
|
catch (InterruptedException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
//We cannot guarantee that this is going to pass due to the possible issue of timing between consumer 1
|
||||||
// and main, but the probability is extremely remote.
|
// and main, but the probability is extremely remote.
|
||||||
assertNull(collector.pollResult());
|
assertNull(collector.pollResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
class OKEverything implements StanzaFilter
|
static class OKEverything implements StanzaFilter
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(Stanza packet)
|
public boolean accept(Stanza packet)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestStanzaCollector extends StanzaCollector
|
static class TestStanzaCollector extends StanzaCollector
|
||||||
{
|
{
|
||||||
protected TestStanzaCollector(XMPPConnection conection, StanzaFilter packetFilter, int size)
|
protected TestStanzaCollector(XMPPConnection conection, StanzaFilter packetFilter, int size)
|
||||||
{
|
{
|
||||||
super(conection, StanzaCollector.newConfiguration().setStanzaFilter(packetFilter).setSize(size));
|
super(conection, StanzaCollector.newConfiguration().setStanzaFilter(packetFilter).setSize(size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestPacket extends Stanza
|
static class TestPacket extends Stanza
|
||||||
{
|
{
|
||||||
public TestPacket(int i)
|
public TestPacket(int i)
|
||||||
{
|
{
|
||||||
setStanzaId(String.valueOf(i));
|
setStanzaId(String.valueOf(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toXML()
|
public String toXML()
|
||||||
{
|
{
|
||||||
return "<packetId>" + getStanzaId() + "</packetId>";
|
return "<packetId>" + getStanzaId() + "</packetId>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toXML();
|
return toXML();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smack.sasl;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -38,14 +39,14 @@ public class DigestMd5SaslTest extends AbstractSaslTest {
|
||||||
super(saslMechanism);
|
super(saslMechanism);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void runTest(boolean useAuthzid) throws NotConnectedException, SmackException, InterruptedException, XmppStringprepException {
|
protected void runTest(boolean useAuthzid) throws NotConnectedException, SmackException, InterruptedException, XmppStringprepException, UnsupportedEncodingException {
|
||||||
EntityBareJid authzid = null;
|
EntityBareJid authzid = null;
|
||||||
if (useAuthzid) {
|
if (useAuthzid) {
|
||||||
authzid = JidCreate.entityBareFrom("shazbat@xmpp.org");
|
authzid = JidCreate.entityBareFrom("shazbat@xmpp.org");
|
||||||
}
|
}
|
||||||
saslMechanism.authenticate("florian", "irrelevant", JidCreate.domainBareFrom("xmpp.org"), "secret", authzid, null);
|
saslMechanism.authenticate("florian", "irrelevant", JidCreate.domainBareFrom("xmpp.org"), "secret", authzid, null);
|
||||||
byte[] response = saslMechanism.evaluateChallenge(challengeBytes);
|
byte[] response = saslMechanism.evaluateChallenge(challengeBytes);
|
||||||
String responseString = new String(response);
|
String responseString = new String(response, StringUtils.UTF8);
|
||||||
String[] responseParts = responseString.split(",");
|
String[] responseParts = responseString.split(",");
|
||||||
Map<String, String> responsePairs = new HashMap<String, String>();
|
Map<String, String> responsePairs = new HashMap<String, String>();
|
||||||
for (String part : responseParts) {
|
for (String part : responseParts) {
|
||||||
|
|
|
@ -710,8 +710,8 @@ public class PacketParserUtilsTest {
|
||||||
try {
|
try {
|
||||||
PacketParserUtils.parseMessage(PacketParserUtils.getParserFor(invalidControl));
|
PacketParserUtils.parseMessage(PacketParserUtils.getParserFor(invalidControl));
|
||||||
fail("Exception should be thrown");
|
fail("Exception should be thrown");
|
||||||
} catch(IllegalStateException e) {
|
} catch(XmlPullParserException e) {
|
||||||
assertTrue(e.getMessage().contains("Invalid Stanza"));
|
assertTrue(e.getMessage().contains("end tag name </body>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
invalidControl = validControl.replace("Good Message Body", "Bad </message> Body");
|
invalidControl = validControl.replace("Good Message Body", "Bad </message> Body");
|
||||||
|
@ -851,6 +851,7 @@ public class PacketParserUtilsTest {
|
||||||
XmlUnitUtils.assertSimilar(saslFailureString, saslFailure.toXML());
|
XmlUnitUtils.assertSimilar(saslFailureString, saslFailure.toXML());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ReferenceEquality")
|
||||||
private static String determineNonDefaultLanguage() {
|
private static String determineNonDefaultLanguage() {
|
||||||
String otherLanguage = "jp";
|
String otherLanguage = "jp";
|
||||||
Locale[] availableLocales = Locale.getAvailableLocales();
|
Locale[] availableLocales = Locale.getAvailableLocales();
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
public class SHA1Test {
|
public class SHA1Test {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testHash() {
|
public void testHash() {
|
||||||
// Test null
|
// Test null
|
||||||
// @TODO - should the StringUtils.hash(String) method be fixed to handle null input?
|
// @TODO - should the StringUtils.hash(String) method be fixed to handle null input?
|
||||||
|
|
|
@ -21,13 +21,15 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
import static org.junit.Assert.assertNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A test case for the StringUtils class.
|
* A test case for the StringUtils class.
|
||||||
*/
|
*/
|
||||||
public class StringUtilsTest {
|
public class StringUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
public void testEscapeForXml() {
|
public void testEscapeForXml() {
|
||||||
String input = null;
|
String input = null;
|
||||||
|
|
||||||
|
@ -67,24 +69,24 @@ public class StringUtilsTest {
|
||||||
assertCharSequenceEquals("It's a good day today", StringUtils.escapeForXml(input));
|
assertCharSequenceEquals("It's a good day today", StringUtils.escapeForXml(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assertCharSequenceEquals(CharSequence expected, CharSequence actual) {
|
public static void assertCharSequenceEquals(CharSequence expected, CharSequence actual) {
|
||||||
assertEquals(expected.toString(), actual.toString());
|
assertEquals(expected.toString(), actual.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEncodeHex() {
|
public void testEncodeHex() throws UnsupportedEncodingException {
|
||||||
String input = "";
|
String input = "";
|
||||||
String output = "";
|
String output = "";
|
||||||
assertEquals(new String(StringUtils.encodeHex(input.getBytes())),
|
assertEquals(new String(StringUtils.encodeHex(input.getBytes(StringUtils.UTF8))),
|
||||||
new String(output.getBytes()));
|
output);
|
||||||
|
|
||||||
input = "foo bar 123";
|
input = "foo bar 123";
|
||||||
output = "666f6f2062617220313233";
|
output = "666f6f2062617220313233";
|
||||||
assertEquals(new String(StringUtils.encodeHex(input.getBytes())),
|
assertEquals(new String(StringUtils.encodeHex(input.getBytes(StringUtils.UTF8))),
|
||||||
new String(output.getBytes()));
|
output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRandomString() {
|
public void testRandomString() {
|
||||||
// Boundary test
|
// Boundary test
|
||||||
String result = StringUtils.randomString(-1);
|
String result = StringUtils.randomString(-1);
|
||||||
|
|
|
@ -40,22 +40,27 @@ class SLF4JLoggingConnectionListener implements ConnectionListener {
|
||||||
logger.debug("({}) Connection authenticated as {}", connection.hashCode(), connection.getUser());
|
logger.debug("({}) Connection authenticated as {}", connection.hashCode(), connection.getUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void connectionClosed() {
|
public void connectionClosed() {
|
||||||
logger.debug("({}) Connection closed", connection.hashCode());
|
logger.debug("({}) Connection closed", connection.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void connectionClosedOnError(Exception e) {
|
public void connectionClosedOnError(Exception e) {
|
||||||
logger.debug("({}) Connection closed due to an exception: {}", connection.hashCode(), e);
|
logger.debug("({}) Connection closed due to an exception: {}", connection.hashCode(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reconnectionFailed(Exception e) {
|
public void reconnectionFailed(Exception e) {
|
||||||
logger.debug("({}) Reconnection failed due to an exception: {}", connection.hashCode(), e);
|
logger.debug("({}) Reconnection failed due to an exception: {}", connection.hashCode(), e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reconnectionSuccessful() {
|
public void reconnectionSuccessful() {
|
||||||
logger.debug("({}) Connection reconnected", connection.hashCode());
|
logger.debug("({}) Connection reconnected", connection.hashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reconnectingIn(int seconds) {
|
public void reconnectingIn(int seconds) {
|
||||||
logger.debug("({}) Connection will reconnect in {}", connection.hashCode(), seconds);
|
logger.debug("({}) Connection will reconnect in {}", connection.hashCode(), seconds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ class SLF4JLoggingPacketListener implements StanzaListener {
|
||||||
this.prefix = Validate.notNull(prefix);
|
this.prefix = Validate.notNull(prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
|
if (SLF4JSmackDebugger.printInterpreted.get() && logger.isDebugEnabled()) {
|
||||||
logger.debug("{}: PKT [{}] '{}'", prefix, packet.getClass().getName(), packet.toXML());
|
logger.debug("{}: PKT [{}] '{}'", prefix, packet.getClass().getName(), packet.toXML());
|
||||||
|
|
|
@ -28,10 +28,12 @@ class SLF4JRawXmlListener implements ReaderListener, WriterListener {
|
||||||
this.logger = Validate.notNull(logger);
|
this.logger = Validate.notNull(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void read(String str) {
|
public void read(String str) {
|
||||||
logger.debug("{}: {}", SLF4JSmackDebugger.RECEIVED_TAG, str);
|
logger.debug("{}: {}", SLF4JSmackDebugger.RECEIVED_TAG, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void write(String str) {
|
public void write(String str) {
|
||||||
logger.debug("{}: {}", SLF4JSmackDebugger.SENT_TAG, str);
|
logger.debug("{}: {}", SLF4JSmackDebugger.SENT_TAG, str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,8 +208,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
packetReaderListener = new StanzaListener() {
|
packetReaderListener = new StanzaListener() {
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processStanza(final Stanza packet) {
|
public void processStanza(final Stanza packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
addReadPacketToTable(dateFormatter, packet);
|
addReadPacketToTable(dateFormatter, packet);
|
||||||
}
|
}
|
||||||
|
@ -223,8 +225,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
packetWriterListener = new StanzaListener() {
|
packetWriterListener = new StanzaListener() {
|
||||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm:ss:SS");
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processStanza(final Stanza packet) {
|
public void processStanza(final Stanza packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
addSentPacketToTable(dateFormatter, packet);
|
addSentPacketToTable(dateFormatter, packet);
|
||||||
}
|
}
|
||||||
|
@ -235,8 +239,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
// 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
|
||||||
public void connectionClosed() {
|
public void connectionClosed() {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusField.setValue("Closed");
|
statusField.setValue("Closed");
|
||||||
EnhancedDebuggerWindow.connectionClosed(EnhancedDebugger.this);
|
EnhancedDebuggerWindow.connectionClosed(EnhancedDebugger.this);
|
||||||
|
@ -245,8 +251,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void connectionClosedOnError(final Exception e) {
|
public void connectionClosedOnError(final Exception e) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusField.setValue("Closed due to an exception");
|
statusField.setValue("Closed due to an exception");
|
||||||
EnhancedDebuggerWindow.connectionClosedOnError(EnhancedDebugger.this, e);
|
EnhancedDebuggerWindow.connectionClosedOnError(EnhancedDebugger.this, e);
|
||||||
|
@ -254,16 +262,20 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
public void reconnectingIn(final int seconds){
|
public void reconnectingIn(final int seconds){
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusField.setValue("Attempt to reconnect in " + seconds + " seconds");
|
statusField.setValue("Attempt to reconnect in " + seconds + " seconds");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reconnectionSuccessful() {
|
public void reconnectionSuccessful() {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusField.setValue("Reconnection stablished");
|
statusField.setValue("Reconnection stablished");
|
||||||
EnhancedDebuggerWindow.connectionEstablished(EnhancedDebugger.this);
|
EnhancedDebuggerWindow.connectionEstablished(EnhancedDebugger.this);
|
||||||
|
@ -271,8 +283,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void reconnectionFailed(Exception e) {
|
public void reconnectionFailed(Exception e) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
statusField.setValue("Reconnection failed");
|
statusField.setValue("Reconnection failed");
|
||||||
}
|
}
|
||||||
|
@ -291,11 +305,13 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
0) {
|
0) {
|
||||||
// CHECKSTYLE:OFF
|
// CHECKSTYLE:OFF
|
||||||
private static final long serialVersionUID = 8136121224474217264L;
|
private static final long serialVersionUID = 8136121224474217264L;
|
||||||
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
@Override
|
||||||
|
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
||||||
// CHECKSTYLE:ON
|
// CHECKSTYLE:ON
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Class<?> getColumnClass(int columnIndex) {
|
public Class<?> getColumnClass(int columnIndex) {
|
||||||
if (columnIndex == 2 || columnIndex == 3) {
|
if (columnIndex == 2 || columnIndex == 3) {
|
||||||
return Icon.class;
|
return Icon.class;
|
||||||
|
@ -344,6 +360,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
JPopupMenu menu = new JPopupMenu();
|
JPopupMenu menu = new JPopupMenu();
|
||||||
JMenuItem menuItem1 = new JMenuItem("Copy");
|
JMenuItem menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -391,6 +408,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
menu = new JPopupMenu();
|
menu = new JPopupMenu();
|
||||||
menuItem1 = new JMenuItem("Copy");
|
menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -401,6 +419,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
JMenuItem menuItem2 = new JMenuItem("Clear");
|
JMenuItem menuItem2 = new JMenuItem("Clear");
|
||||||
menuItem2.addActionListener(new ActionListener() {
|
menuItem2.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
sentText.setText("");
|
sentText.setText("");
|
||||||
}
|
}
|
||||||
|
@ -426,6 +445,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
menu = new JPopupMenu();
|
menu = new JPopupMenu();
|
||||||
menuItem1 = new JMenuItem("Copy");
|
menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -436,6 +456,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem2 = new JMenuItem("Clear");
|
menuItem2 = new JMenuItem("Clear");
|
||||||
menuItem2.addActionListener(new ActionListener() {
|
menuItem2.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
receivedText.setText("");
|
receivedText.setText("");
|
||||||
}
|
}
|
||||||
|
@ -449,8 +470,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
// 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.
|
||||||
ObservableReader debugReader = new ObservableReader(reader);
|
ObservableReader debugReader = new ObservableReader(reader);
|
||||||
readerListener = new ReaderListener() {
|
readerListener = new ReaderListener() {
|
||||||
|
@Override
|
||||||
public void read(final String str) {
|
public void read(final String str) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER &&
|
if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER &&
|
||||||
!EnhancedDebuggerWindow.getInstance().isVisible()) {
|
!EnhancedDebuggerWindow.getInstance().isVisible()) {
|
||||||
|
@ -487,8 +510,10 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
||||||
ObservableWriter debugWriter = new ObservableWriter(writer);
|
ObservableWriter debugWriter = new ObservableWriter(writer);
|
||||||
writerListener = new WriterListener() {
|
writerListener = new WriterListener() {
|
||||||
|
@Override
|
||||||
public void write(final String str) {
|
public void write(final String str) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER &&
|
if (EnhancedDebuggerWindow.PERSISTED_DEBUGGER &&
|
||||||
!EnhancedDebuggerWindow.getInstance().isVisible()) {
|
!EnhancedDebuggerWindow.getInstance().isVisible()) {
|
||||||
|
@ -536,6 +561,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
JPopupMenu menu = new JPopupMenu();
|
JPopupMenu menu = new JPopupMenu();
|
||||||
JMenuItem menuItem = new JMenuItem("Message");
|
JMenuItem menuItem = new JMenuItem("Message");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
adhocMessages.setText(
|
adhocMessages.setText(
|
||||||
"<message to=\"\" id=\""
|
"<message to=\"\" id=\""
|
||||||
|
@ -547,6 +573,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem = new JMenuItem("IQ Get");
|
menuItem = new JMenuItem("IQ Get");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
adhocMessages.setText(
|
adhocMessages.setText(
|
||||||
"<iq type=\"get\" to=\"\" id=\""
|
"<iq type=\"get\" to=\"\" id=\""
|
||||||
|
@ -558,6 +585,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem = new JMenuItem("IQ Set");
|
menuItem = new JMenuItem("IQ Set");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
adhocMessages.setText(
|
adhocMessages.setText(
|
||||||
"<iq type=\"set\" to=\"\" id=\""
|
"<iq type=\"set\" to=\"\" id=\""
|
||||||
|
@ -569,6 +597,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem = new JMenuItem("Presence");
|
menuItem = new JMenuItem("Presence");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
adhocMessages.setText(
|
adhocMessages.setText(
|
||||||
"<presence to=\"\" id=\"" + StringUtils.randomString(5) + "-X\"/>");
|
"<presence to=\"\" id=\"" + StringUtils.randomString(5) + "-X\"/>");
|
||||||
|
@ -579,6 +608,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem = new JMenuItem("Send");
|
menuItem = new JMenuItem("Send");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
if (!"".equals(adhocMessages.getText())) {
|
if (!"".equals(adhocMessages.getText())) {
|
||||||
AdHocPacket packetToSend = new AdHocPacket(adhocMessages.getText());
|
AdHocPacket packetToSend = new AdHocPacket(adhocMessages.getText());
|
||||||
|
@ -595,6 +625,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem = new JMenuItem("Clear");
|
menuItem = new JMenuItem("Clear");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
adhocMessages.setText(null);
|
adhocMessages.setText(null);
|
||||||
}
|
}
|
||||||
|
@ -709,7 +740,8 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
new Object[]{"Type", "Received", "Sent"}) {
|
new Object[]{"Type", "Received", "Sent"}) {
|
||||||
// CHECKSTYLE:OFF
|
// CHECKSTYLE:OFF
|
||||||
private static final long serialVersionUID = -6793886085109589269L;
|
private static final long serialVersionUID = -6793886085109589269L;
|
||||||
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
@Override
|
||||||
|
public boolean isCellEditable(int rowIndex, int mColIndex) {
|
||||||
// CHECKSTYLE:ON
|
// CHECKSTYLE:ON
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -726,6 +758,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
tabbedPane.setToolTipTextAt(4, "Information and statistics about the debugged connection");
|
tabbedPane.setToolTipTextAt(4, "Information and statistics about the debugged connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader newConnectionReader(Reader newReader) {
|
public Reader newConnectionReader(Reader newReader) {
|
||||||
((ObservableReader) reader).removeReaderListener(readerListener);
|
((ObservableReader) reader).removeReaderListener(readerListener);
|
||||||
ObservableReader debugReader = new ObservableReader(newReader);
|
ObservableReader debugReader = new ObservableReader(newReader);
|
||||||
|
@ -734,6 +767,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer newConnectionWriter(Writer newWriter) {
|
public Writer newConnectionWriter(Writer newWriter) {
|
||||||
((ObservableWriter) writer).removeWriterListener(writerListener);
|
((ObservableWriter) writer).removeWriterListener(writerListener);
|
||||||
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
||||||
|
@ -746,6 +780,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
public void userHasLogged(final EntityFullJid user) {
|
public void userHasLogged(final EntityFullJid user) {
|
||||||
final EnhancedDebugger debugger = this;
|
final EnhancedDebugger debugger = this;
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
userField.setText(user.toString());
|
userField.setText(user.toString());
|
||||||
EnhancedDebuggerWindow.userHasLogged(debugger, user.toString());
|
EnhancedDebuggerWindow.userHasLogged(debugger, user.toString());
|
||||||
|
@ -757,18 +792,22 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader getReader() {
|
public Reader getReader() {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer getWriter() {
|
public Writer getWriter() {
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getReaderListener() {
|
public StanzaListener getReaderListener() {
|
||||||
return packetReaderListener;
|
return packetReaderListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getWriterListener() {
|
public StanzaListener getWriterListener() {
|
||||||
return packetWriterListener;
|
return packetWriterListener;
|
||||||
}
|
}
|
||||||
|
@ -801,6 +840,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
*/
|
*/
|
||||||
private void addReadPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
private void addReadPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String messageType;
|
String messageType;
|
||||||
Jid from = packet.getFrom();
|
Jid from = packet.getFrom();
|
||||||
|
@ -862,6 +902,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
*/
|
*/
|
||||||
private void addSentPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
private void addSentPacketToTable(final SimpleDateFormat dateFormatter, final Stanza packet) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
String messageType;
|
String messageType;
|
||||||
Jid to = packet.getTo();
|
Jid to = packet.getTo();
|
||||||
|
@ -978,9 +1019,9 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
* The whole text to send must be passed to the constructor. This implies that the client of
|
* The whole text to send must be passed to the constructor. This implies that the client of
|
||||||
* this class is responsible for sending a valid text to the constructor.
|
* this class is responsible for sending a valid text to the constructor.
|
||||||
*/
|
*/
|
||||||
private class AdHocPacket extends Stanza {
|
private static class AdHocPacket extends Stanza {
|
||||||
|
|
||||||
private String text;
|
private final String text;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new AdHocPacket with the text to send. The passed text must be a valid text to
|
* Create a new AdHocPacket with the text to send. The passed text must be a valid text to
|
||||||
|
@ -992,6 +1033,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String toXML() {
|
public String toXML() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1048,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
/**
|
/**
|
||||||
* Listens for debug window popup dialog events.
|
* Listens for debug window popup dialog events.
|
||||||
*/
|
*/
|
||||||
private class PopupListener extends MouseAdapter {
|
private static class PopupListener extends MouseAdapter {
|
||||||
|
|
||||||
JPopupMenu popup;
|
JPopupMenu popup;
|
||||||
|
|
||||||
|
@ -1014,10 +1056,12 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
popup = popupMenu;
|
popup = popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
@ -1039,6 +1083,7 @@ public class EnhancedDebugger implements SmackDebugger {
|
||||||
this.table = table;
|
this.table = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void valueChanged(ListSelectionEvent e) {
|
public void valueChanged(ListSelectionEvent e) {
|
||||||
if (table.getSelectedRow() == -1) {
|
if (table.getSelectedRow() == -1) {
|
||||||
// Clear the messageTextArea since there is none packet selected
|
// Clear the messageTextArea since there is none packet selected
|
||||||
|
|
|
@ -203,13 +203,14 @@ public final class EnhancedDebuggerWindow {
|
||||||
* a tab panel for each connection that is being debugged.
|
* a tab panel for each connection that is being debugged.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
private void createDebug() {
|
private void createDebug() {
|
||||||
|
|
||||||
frame = new JFrame("Smack Debug Window");
|
frame = new JFrame("Smack Debug Window");
|
||||||
|
|
||||||
if (!PERSISTED_DEBUGGER) {
|
if (!PERSISTED_DEBUGGER) {
|
||||||
// Add listener for window closing event
|
// Add listener for window closing event
|
||||||
frame.addWindowListener(new WindowAdapter() {
|
frame.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
public void windowClosing(WindowEvent evt) {
|
public void windowClosing(WindowEvent evt) {
|
||||||
rootWindowClosing(evt);
|
rootWindowClosing(evt);
|
||||||
}
|
}
|
||||||
|
@ -280,6 +281,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
// Add a menu item that allows to close the current selected tab
|
// Add a menu item that allows to close the current selected tab
|
||||||
JMenuItem menuItem = new JMenuItem("Close");
|
JMenuItem menuItem = new JMenuItem("Close");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Remove the selected tab pane if it's not the Smack info pane
|
// Remove the selected tab pane if it's not the Smack info pane
|
||||||
if (tabbedPane.getSelectedIndex() < tabbedPane.getComponentCount() - 1) {
|
if (tabbedPane.getSelectedIndex() < tabbedPane.getComponentCount() - 1) {
|
||||||
|
@ -301,6 +303,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
// Add a menu item that allows to close all the tabs that have their connections closed
|
// Add a menu item that allows to close all the tabs that have their connections closed
|
||||||
menuItem = new JMenuItem("Close All Not Active");
|
menuItem = new JMenuItem("Close All Not Active");
|
||||||
menuItem.addActionListener(new ActionListener() {
|
menuItem.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
ArrayList<EnhancedDebugger> debuggersToRemove = new ArrayList<EnhancedDebugger>();
|
ArrayList<EnhancedDebugger> debuggersToRemove = new ArrayList<EnhancedDebugger>();
|
||||||
// Remove all the debuggers of which their connections are no longer valid
|
// Remove all the debuggers of which their connections are no longer valid
|
||||||
|
@ -348,7 +351,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
debugger.cancel();
|
debugger.cancel();
|
||||||
}
|
}
|
||||||
// Release any reference to the debuggers
|
// Release any reference to the debuggers
|
||||||
debuggers.removeAll(debuggers);
|
debuggers.clear();
|
||||||
// Release the default instance
|
// Release the default instance
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
|
@ -356,7 +359,7 @@ public final class EnhancedDebuggerWindow {
|
||||||
/**
|
/**
|
||||||
* Listens for debug window popup dialog events.
|
* Listens for debug window popup dialog events.
|
||||||
*/
|
*/
|
||||||
private class PopupListener extends MouseAdapter {
|
private static class PopupListener extends MouseAdapter {
|
||||||
|
|
||||||
JPopupMenu popup;
|
JPopupMenu popup;
|
||||||
|
|
||||||
|
@ -364,10 +367,12 @@ public final class EnhancedDebuggerWindow {
|
||||||
popup = popupMenu;
|
popup = popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
|
|
||||||
// Add listener for window closing event
|
// Add listener for window closing event
|
||||||
frame.addWindowListener(new WindowAdapter() {
|
frame.addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
public void windowClosing(WindowEvent evt) {
|
public void windowClosing(WindowEvent evt) {
|
||||||
rootWindowClosing(evt);
|
rootWindowClosing(evt);
|
||||||
}
|
}
|
||||||
|
@ -114,6 +115,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
JPopupMenu menu = new JPopupMenu();
|
JPopupMenu menu = new JPopupMenu();
|
||||||
JMenuItem menuItem1 = new JMenuItem("Copy");
|
JMenuItem menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -124,6 +126,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
|
|
||||||
JMenuItem menuItem2 = new JMenuItem("Clear");
|
JMenuItem menuItem2 = new JMenuItem("Clear");
|
||||||
menuItem2.addActionListener(new ActionListener() {
|
menuItem2.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
sentText1.setText("");
|
sentText1.setText("");
|
||||||
sentText2.setText("");
|
sentText2.setText("");
|
||||||
|
@ -151,6 +154,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
menu = new JPopupMenu();
|
menu = new JPopupMenu();
|
||||||
menuItem1 = new JMenuItem("Copy");
|
menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -161,6 +165,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem2 = new JMenuItem("Clear");
|
menuItem2 = new JMenuItem("Clear");
|
||||||
menuItem2.addActionListener(new ActionListener() {
|
menuItem2.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
receivedText1.setText("");
|
receivedText1.setText("");
|
||||||
receivedText2.setText("");
|
receivedText2.setText("");
|
||||||
|
@ -188,6 +193,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
menu = new JPopupMenu();
|
menu = new JPopupMenu();
|
||||||
menuItem1 = new JMenuItem("Copy");
|
menuItem1 = new JMenuItem("Copy");
|
||||||
menuItem1.addActionListener(new ActionListener() {
|
menuItem1.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
// Get the clipboard
|
// Get the clipboard
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
@ -198,6 +204,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
|
|
||||||
menuItem2 = new JMenuItem("Clear");
|
menuItem2 = new JMenuItem("Clear");
|
||||||
menuItem2.addActionListener(new ActionListener() {
|
menuItem2.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
interpretedText1.setText("");
|
interpretedText1.setText("");
|
||||||
interpretedText2.setText("");
|
interpretedText2.setText("");
|
||||||
|
@ -219,6 +226,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
// 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.
|
||||||
ObservableReader debugReader = new ObservableReader(reader);
|
ObservableReader debugReader = new ObservableReader(reader);
|
||||||
readerListener = new ReaderListener() {
|
readerListener = new ReaderListener() {
|
||||||
|
@Override
|
||||||
public void read(String str) {
|
public void read(String str) {
|
||||||
int index = str.lastIndexOf(">");
|
int index = str.lastIndexOf(">");
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
|
@ -242,6 +250,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
// Create a special Writer that wraps the main Writer and logs data to the GUI.
|
||||||
ObservableWriter debugWriter = new ObservableWriter(writer);
|
ObservableWriter debugWriter = new ObservableWriter(writer);
|
||||||
writerListener = new WriterListener() {
|
writerListener = new WriterListener() {
|
||||||
|
@Override
|
||||||
public void write(String str) {
|
public void write(String str) {
|
||||||
sentText1.append(str);
|
sentText1.append(str);
|
||||||
sentText2.append(str);
|
sentText2.append(str);
|
||||||
|
@ -262,6 +271,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
// the GUI. This is what we call "interpreted" packet data, since it's the packet
|
// 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.
|
// data as Smack sees it and not as it's coming in as raw XML.
|
||||||
listener = new StanzaListener() {
|
listener = new StanzaListener() {
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
interpretedText1.append(packet.toXML().toString());
|
interpretedText1.append(packet.toXML().toString());
|
||||||
interpretedText2.append(packet.toXML().toString());
|
interpretedText2.append(packet.toXML().toString());
|
||||||
|
@ -286,17 +296,19 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
/**
|
/**
|
||||||
* Listens for debug window popup dialog events.
|
* Listens for debug window popup dialog events.
|
||||||
*/
|
*/
|
||||||
private class PopupListener extends MouseAdapter {
|
private static class PopupListener extends MouseAdapter {
|
||||||
JPopupMenu popup;
|
JPopupMenu popup;
|
||||||
|
|
||||||
PopupListener(JPopupMenu popupMenu) {
|
PopupListener(JPopupMenu popupMenu) {
|
||||||
popup = popupMenu;
|
popup = popupMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
maybeShowPopup(e);
|
maybeShowPopup(e);
|
||||||
}
|
}
|
||||||
|
@ -308,6 +320,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader newConnectionReader(Reader newReader) {
|
public Reader newConnectionReader(Reader newReader) {
|
||||||
((ObservableReader)reader).removeReaderListener(readerListener);
|
((ObservableReader)reader).removeReaderListener(readerListener);
|
||||||
ObservableReader debugReader = new ObservableReader(newReader);
|
ObservableReader debugReader = new ObservableReader(newReader);
|
||||||
|
@ -316,6 +329,7 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer newConnectionWriter(Writer newWriter) {
|
public Writer newConnectionWriter(Writer newWriter) {
|
||||||
((ObservableWriter)writer).removeWriterListener(writerListener);
|
((ObservableWriter)writer).removeWriterListener(writerListener);
|
||||||
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
ObservableWriter debugWriter = new ObservableWriter(newWriter);
|
||||||
|
@ -332,18 +346,22 @@ public class LiteDebugger implements SmackDebugger {
|
||||||
frame.setTitle(title);
|
frame.setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Reader getReader() {
|
public Reader getReader() {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Writer getWriter() {
|
public Writer getWriter() {
|
||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getReaderListener() {
|
public StanzaListener getReaderListener() {
|
||||||
return listener;
|
return listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public StanzaListener getWriterListener() {
|
public StanzaListener getWriterListener() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.carbons;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
import org.jivesoftware.smackx.carbons.packet.CarbonExtension.Direction;
|
||||||
|
|
||||||
|
public interface CarbonCopyReceivedListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked when a new carbon copy was received.
|
||||||
|
*
|
||||||
|
* @param direction the direction of the carbon copy.
|
||||||
|
* @param carbonCopy the carbon copy itself.
|
||||||
|
* @param wrappingMessage the message wrapping the carbon copy.
|
||||||
|
*/
|
||||||
|
void onCarbonCopyReceived(Direction direction, Message carbonCopy, Message wrappingMessage);
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2013-2014 Georg Lukas
|
* Copyright 2013-2014 Georg Lukas, 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.
|
||||||
|
@ -17,37 +17,54 @@
|
||||||
package org.jivesoftware.smackx.carbons;
|
package org.jivesoftware.smackx.carbons;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ExceptionCallback;
|
|
||||||
import org.jivesoftware.smack.AbstractConnectionListener;
|
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
import org.jivesoftware.smack.ExceptionCallback;
|
||||||
|
import org.jivesoftware.smack.Manager;
|
||||||
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.SmackException.NotConnectedException;
|
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
|
||||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
|
||||||
import org.jivesoftware.smack.Manager;
|
|
||||||
import org.jivesoftware.smack.StanzaListener;
|
import org.jivesoftware.smack.StanzaListener;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
|
import org.jivesoftware.smack.filter.AndFilter;
|
||||||
|
import org.jivesoftware.smack.filter.FromMatchesFilter;
|
||||||
|
import org.jivesoftware.smack.filter.OrFilter;
|
||||||
|
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||||
|
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
|
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
||||||
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.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
|
||||||
import org.jivesoftware.smackx.carbons.packet.Carbon;
|
import org.jivesoftware.smackx.carbons.packet.Carbon;
|
||||||
|
import org.jivesoftware.smackx.carbons.packet.CarbonExtension;
|
||||||
|
import org.jivesoftware.smackx.carbons.packet.CarbonExtension.Direction;
|
||||||
import org.jivesoftware.smackx.carbons.packet.CarbonExtension.Private;
|
import org.jivesoftware.smackx.carbons.packet.CarbonExtension.Private;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||||
|
import org.jxmpp.jid.EntityFullJid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stanza(/Packet) extension for XEP-0280: Message Carbons. This class implements
|
* Manager for XEP-0280: Message Carbons. This class implements the manager for registering {@link CarbonExtension}
|
||||||
* the manager for registering {@link CarbonExtension} support, enabling and disabling
|
* support, enabling and disabling message carbons, and for {@link CarbonCopyReceivedListener}.
|
||||||
* message carbons.
|
* <p>
|
||||||
*
|
* Note that <b>it is important to match the 'from' attribute of the message wrapping a carbon copy</b>, as otherwise it would
|
||||||
* You should call enableCarbons() before sending your first undirected
|
* may be possible for others to impersonate users. Smack's CarbonManager takes care of that in
|
||||||
* presence.
|
* {@link CarbonCopyReceivedListener}s which where registered with
|
||||||
|
* {@link #addCarbonCopyReceivedListener(CarbonCopyReceivedListener)}.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* You should call enableCarbons() before sending your first undirected presence (aka. the "initial presence").
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Georg Lukas
|
* @author Georg Lukas
|
||||||
|
* @author Florian Schmaus
|
||||||
*/
|
*/
|
||||||
public final class CarbonManager extends Manager {
|
public final class CarbonManager extends Manager {
|
||||||
|
|
||||||
|
@ -55,18 +72,49 @@ public final class CarbonManager extends Manager {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final StanzaFilter CARBON_EXTENSION_FILTER =
|
||||||
|
// @formatter:off
|
||||||
|
new AndFilter(
|
||||||
|
new OrFilter(
|
||||||
|
new StanzaExtensionFilter(CarbonExtension.Direction.sent.name(), CarbonExtension.NAMESPACE),
|
||||||
|
new StanzaExtensionFilter(CarbonExtension.Direction.received.name(), CarbonExtension.NAMESPACE)
|
||||||
|
),
|
||||||
|
StanzaTypeFilter.MESSAGE
|
||||||
|
);
|
||||||
|
// @formatter:on
|
||||||
|
|
||||||
|
private final Set<CarbonCopyReceivedListener> listeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
private volatile boolean enabled_state = false;
|
private volatile boolean enabled_state = false;
|
||||||
|
|
||||||
|
private final StanzaListener carbonsListener;
|
||||||
|
|
||||||
private CarbonManager(XMPPConnection connection) {
|
private CarbonManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
sdm.addFeature(CarbonExtension.NAMESPACE);
|
sdm.addFeature(CarbonExtension.NAMESPACE);
|
||||||
|
|
||||||
|
carbonsListener = new StanzaListener() {
|
||||||
|
@Override
|
||||||
|
public void processStanza(final Stanza stanza) throws NotConnectedException, InterruptedException {
|
||||||
|
final Message wrappingMessage = (Message) stanza;
|
||||||
|
final CarbonExtension carbonExtension = CarbonExtension.from(wrappingMessage);
|
||||||
|
final Direction direction = carbonExtension.getDirection();
|
||||||
|
final Forwarded forwarded = carbonExtension.getForwarded();
|
||||||
|
final Message carbonCopy = (Message) forwarded.getForwardedStanza();
|
||||||
|
for (CarbonCopyReceivedListener listener : listeners) {
|
||||||
|
listener.onCarbonCopyReceived(direction, carbonCopy, wrappingMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
connection.addConnectionListener(new AbstractConnectionListener() {
|
connection.addConnectionListener(new AbstractConnectionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void connectionClosed() {
|
public void connectionClosed() {
|
||||||
|
@ -74,6 +122,8 @@ public final class CarbonManager extends Manager {
|
||||||
// because we also reset in authenticated() if the stream got not resumed, but for maximum correctness,
|
// because we also reset in authenticated() if the stream got not resumed, but for maximum correctness,
|
||||||
// also reset here.
|
// also reset here.
|
||||||
enabled_state = false;
|
enabled_state = false;
|
||||||
|
boolean removed = connection().removeSyncStanzaListener(carbonsListener);
|
||||||
|
assert(removed);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||||
|
@ -81,8 +131,27 @@ public final class CarbonManager extends Manager {
|
||||||
// Non-resumed XMPP sessions always start with disabled carbons
|
// Non-resumed XMPP sessions always start with disabled carbons
|
||||||
enabled_state = false;
|
enabled_state = false;
|
||||||
}
|
}
|
||||||
|
addCarbonsListener(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addCarbonsListener(connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCarbonsListener(XMPPConnection connection) {
|
||||||
|
EntityFullJid localAddress = connection.getUser();
|
||||||
|
if (localAddress == null) {
|
||||||
|
// We where not connected yet and thus we don't know our XMPP address at the moment, which we need to match incoming
|
||||||
|
// carbons securely. Abort here. The ConnectionListener above will eventually setup the carbons listener.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XEP-0280 § 11. Security Considerations "Any forwarded copies received by a Carbons-enabled client MUST be
|
||||||
|
// from that user's bare JID; any copies that do not meet this requirement MUST be ignored." Otherwise, if
|
||||||
|
// those copies do not get ignored, malicious users may be able to impersonate other users. That is why the
|
||||||
|
// 'from' matcher is important here.
|
||||||
|
connection.addSyncStanzaListener(carbonsListener, new AndFilter(CARBON_EXTENSION_FILTER,
|
||||||
|
FromMatchesFilter.createBare(localAddress)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -113,6 +182,28 @@ public final class CarbonManager extends Manager {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a carbon copy received listener.
|
||||||
|
*
|
||||||
|
* @param listener the listener to register.
|
||||||
|
* @return <code>true</code> if the filter was not already registered.
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public boolean addCarbonCopyReceivedListener(CarbonCopyReceivedListener listener) {
|
||||||
|
return listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a carbon copy received listener.
|
||||||
|
*
|
||||||
|
* @param listener the listener to register.
|
||||||
|
* @return <code>true</code> if the filter was registered.
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public boolean removeCarbonCopyReceivedListener(CarbonCopyReceivedListener listener) {
|
||||||
|
return listeners.remove(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if XMPP Carbons are supported by the server.
|
* Returns true if XMPP Carbons are supported by the server.
|
||||||
*
|
*
|
||||||
|
@ -181,6 +272,7 @@ public final class CarbonManager extends Manager {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
connection().sendIqWithResponseCallback(setIQ, new StanzaListener() {
|
connection().sendIqWithResponseCallback(setIQ, new StanzaListener() {
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
enabled_state = use;
|
enabled_state = use;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ public abstract class AbstractHttpOverXmpp extends IQ {
|
||||||
this.version = Objects.requireNonNull(builder.version, "version must not be null");
|
this.version = Objects.requireNonNull(builder.version, "version must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||||
IQChildElementXmlStringBuilder builder = getIQHoxtChildElementBuilder(xml);
|
IQChildElementXmlStringBuilder builder = getIQHoxtChildElementBuilder(xml);
|
||||||
builder.optAppend(headers);
|
builder.optAppend(headers);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright © 2016 Florian Schmaus
|
* Copyright © 2016-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,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.iot.control.element;
|
package org.jivesoftware.smackx.iot.control.element;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -31,7 +32,21 @@ public class IoTSetRequest extends IQ {
|
||||||
public IoTSetRequest(Collection<? extends SetData> setData) {
|
public IoTSetRequest(Collection<? extends SetData> setData) {
|
||||||
super(ELEMENT, NAMESPACE);
|
super(ELEMENT, NAMESPACE);
|
||||||
setType(Type.set);
|
setType(Type.set);
|
||||||
this.setData = Collections.unmodifiableCollection(setData);
|
|
||||||
|
/*
|
||||||
|
* Ugly workaround for the following error prone false positive:
|
||||||
|
*
|
||||||
|
* IoTSetRequest.java:34: error: incompatible types: Collection<CAP#1> cannot be converted to Collection<SetData>
|
||||||
|
* this.setData = Collections.unmodifiableCollection(setDataA);
|
||||||
|
* ^
|
||||||
|
* where CAP#1 is a fresh type-variable:
|
||||||
|
* CAP#1 extends SetData from capture of ? extends SetData
|
||||||
|
*/
|
||||||
|
Collection<SetData> tmp = new ArrayList<>(setData.size());
|
||||||
|
for (SetData data : setData) {
|
||||||
|
tmp.add(data);
|
||||||
|
}
|
||||||
|
this.setData = Collections.unmodifiableCollection(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<SetData> getSetData() {
|
public Collection<SetData> getSetData() {
|
||||||
|
|
|
@ -30,7 +30,7 @@ public abstract class SetData implements NamedElement {
|
||||||
DOUBLE,
|
DOUBLE,
|
||||||
;
|
;
|
||||||
|
|
||||||
private String toStringCache;
|
private final String toStringCache;
|
||||||
|
|
||||||
private Type() {
|
private Type() {
|
||||||
toStringCache = this.name().toLowerCase(Locale.US);
|
toStringCache = this.name().toLowerCase(Locale.US);
|
||||||
|
|
|
@ -61,6 +61,7 @@ public final class IoTDataManager extends IoTManager {
|
||||||
// Ensure a IoTDataManager exists for every connection.
|
// Ensure a IoTDataManager exists for every connection.
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
if (!isAutoEnableActive()) return;
|
if (!isAutoEnableActive()) return;
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
|
|
|
@ -74,6 +74,7 @@ public final class IoTDiscoveryManager extends Manager {
|
||||||
// Ensure a IoTProvisioningManager exists for every connection.
|
// Ensure a IoTProvisioningManager exists for every connection.
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
if (!IoTManager.isAutoEnableActive()) return;
|
if (!IoTManager.isAutoEnableActive()) return;
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
|
|
|
@ -62,6 +62,7 @@ public final class NodeInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@SuppressWarnings("ReferenceEquality")
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (this == EMPTY) {
|
if (this == EMPTY) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -82,6 +82,7 @@ public final class IoTProvisioningManager extends Manager {
|
||||||
// Ensure a IoTProvisioningManager exists for every connection.
|
// Ensure a IoTProvisioningManager exists for every connection.
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
if (!IoTManager.isAutoEnableActive()) return;
|
if (!IoTManager.isAutoEnableActive()) return;
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
|
|
|
@ -267,7 +267,7 @@ public class MultiUserChatLight {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
connection.createStanzaCollectorAndSend(createMUCLightIQ).nextResultOrThrow();
|
connection.createStanzaCollectorAndSend(createMUCLightIQ).nextResultOrThrow();
|
||||||
} catch (InterruptedException | NoResponseException | XMPPErrorException e) {
|
} catch (NotConnectedException | InterruptedException | NoResponseException | XMPPErrorException e) {
|
||||||
removeConnectionCallbacks();
|
removeConnectionCallbacks();
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.jxmpp.jid.Jid;
|
||||||
*
|
*
|
||||||
* @see <a href="https://xmpp.org/extensions/xep-0296.html">XEP-0296: Best Practices for Resource Locking</a>
|
* @see <a href="https://xmpp.org/extensions/xep-0296.html">XEP-0296: Best Practices for Resource Locking</a>
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("FunctionalInterfaceClash")
|
||||||
public final class ChatManager extends Manager {
|
public final class ChatManager extends Manager {
|
||||||
|
|
||||||
private static final Map<XMPPConnection, ChatManager> INSTANCES = new WeakHashMap<>();
|
private static final Map<XMPPConnection, ChatManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
@ -69,7 +70,7 @@ public final class ChatManager extends Manager {
|
||||||
// @FORMATTER:OFF
|
// @FORMATTER:OFF
|
||||||
private static final StanzaFilter MESSAGE_FILTER = new AndFilter(
|
private static final StanzaFilter MESSAGE_FILTER = new AndFilter(
|
||||||
MessageTypeFilter.NORMAL_OR_CHAT,
|
MessageTypeFilter.NORMAL_OR_CHAT,
|
||||||
new OrFilter(MessageWithBodiesFilter.INSTANCE), new StanzaExtensionFilter(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE)
|
new OrFilter(MessageWithBodiesFilter.INSTANCE, new StanzaExtensionFilter(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE))
|
||||||
);
|
);
|
||||||
|
|
||||||
private static final StanzaFilter OUTGOING_MESSAGE_FILTER = new AndFilter(
|
private static final StanzaFilter OUTGOING_MESSAGE_FILTER = new AndFilter(
|
||||||
|
@ -188,22 +189,84 @@ public final class ChatManager extends Manager {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addListener(IncomingChatMessageListener listener) {
|
/**
|
||||||
|
* Add a new listener for incoming chat messages.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @return <code>true</code> if the listener was not already added.
|
||||||
|
*/
|
||||||
|
public boolean addIncomingListener(IncomingChatMessageListener listener) {
|
||||||
return incomingListeners.add(listener);
|
return incomingListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new listener for incoming chat messages.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @return <code>true</code> if the listener was not already added.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@SuppressWarnings("FunctionalInterfaceClash")
|
||||||
|
public boolean addListener(IncomingChatMessageListener listener) {
|
||||||
|
return addIncomingListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an incoming chat message listener.
|
||||||
|
*
|
||||||
|
* @param listener the listener to remove.
|
||||||
|
* @return <code>true</code> if the listener was active and got removed.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("FunctionalInterfaceClash")
|
||||||
public boolean removeListener(IncomingChatMessageListener listener) {
|
public boolean removeListener(IncomingChatMessageListener listener) {
|
||||||
return incomingListeners.remove(listener);
|
return incomingListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean addListener(OutgoingChatMessageListener listener) {
|
/**
|
||||||
|
* Add a new listener for outgoing chat messages.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @return <code>true</code> if the listener was not already added.
|
||||||
|
*/
|
||||||
|
public boolean addOutgoingListener(OutgoingChatMessageListener listener) {
|
||||||
return outgoingListeners.add(listener);
|
return outgoingListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removeOutoingLIstener(OutgoingChatMessageListener listener) {
|
/**
|
||||||
|
* Add a new listener for incoming chat messages.
|
||||||
|
*
|
||||||
|
* @param listener the listener to add.
|
||||||
|
* @return <code>true</code> if the listener was not already added.
|
||||||
|
* @deprecated use {@link #addOutgoingListener(OutgoingChatMessageListener)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@SuppressWarnings("FunctionalInterfaceClash")
|
||||||
|
public boolean addListener(OutgoingChatMessageListener listener) {
|
||||||
|
return addOutgoingListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an outgoing chat message listener.
|
||||||
|
*
|
||||||
|
* @param listener the listener to remove.
|
||||||
|
* @return <code>true</code> if the listener was active and got removed.
|
||||||
|
*/
|
||||||
|
public boolean removeListener(OutgoingChatMessageListener listener) {
|
||||||
return outgoingListeners.remove(listener);
|
return outgoingListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an outgoing chat message listener.
|
||||||
|
*
|
||||||
|
* @param listener the listener to remove.
|
||||||
|
* @return <code>true</code> if the listener was active and got removed.
|
||||||
|
* @deprecated use {@link #removeListener(OutgoingChatMessageListener)} instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public boolean removeOutoingLIstener(OutgoingChatMessageListener listener) {
|
||||||
|
return removeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start a new or retrieve the existing chat with <code>jid</code>.
|
* Start a new or retrieve the existing chat with <code>jid</code>.
|
||||||
*
|
*
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class AMPManager {
|
||||||
// The ServiceDiscoveryManager class should have been already initialized
|
// The ServiceDiscoveryManager class should have been already initialized
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
AMPManager.setServiceEnabled(connection, true);
|
AMPManager.setServiceEnabled(connection, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public class AttentionExtension implements ExtensionElement {
|
||||||
*
|
*
|
||||||
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
* @see org.jivesoftware.smack.packet.PacketExtension#getElementName()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT_NAME;
|
return ELEMENT_NAME;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +57,7 @@ public class AttentionExtension implements ExtensionElement {
|
||||||
*
|
*
|
||||||
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
* @see org.jivesoftware.smack.packet.PacketExtension#getNamespace()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return NAMESPACE;
|
return NAMESPACE;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +67,7 @@ public class AttentionExtension implements ExtensionElement {
|
||||||
*
|
*
|
||||||
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
* @see org.jivesoftware.smack.packet.PacketExtension#toXML()
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String toXML() {
|
public String toXML() {
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
sb.append('<').append(getElementName()).append(" xmlns=\"").append(
|
sb.append('<').append(getElementName()).append(" xmlns=\"").append(
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.blocking;
|
||||||
|
|
||||||
|
public interface AllJidsUnblockedListener {
|
||||||
|
|
||||||
|
void onAllJidsUnblocked();
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2016 Fernando Ramirez, Florian Schmaus
|
* Copyright 2016-2017 Fernando Ramirez, 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,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
import org.jivesoftware.smack.AbstractConnectionListener;
|
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||||
|
@ -82,6 +84,12 @@ public final class BlockingCommandManager extends Manager {
|
||||||
return blockingCommandManager;
|
return blockingCommandManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Set<AllJidsUnblockedListener> allJidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
|
private final Set<JidsBlockedListener> jidsBlockedListeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
|
private final Set<JidsUnblockedListener> jidsUnblockedListeners = new CopyOnWriteArraySet<>();
|
||||||
|
|
||||||
private BlockingCommandManager(XMPPConnection connection) {
|
private BlockingCommandManager(XMPPConnection connection) {
|
||||||
super(connection);
|
super(connection);
|
||||||
|
|
||||||
|
@ -99,6 +107,10 @@ public final class BlockingCommandManager extends Manager {
|
||||||
List<Jid> blockedJids = blockContactIQ.getJids();
|
List<Jid> blockedJids = blockContactIQ.getJids();
|
||||||
blockListCached.addAll(blockedJids);
|
blockListCached.addAll(blockedJids);
|
||||||
|
|
||||||
|
for (JidsBlockedListener listener : jidsBlockedListeners) {
|
||||||
|
listener.onJidsBlocked(blockedJids);
|
||||||
|
}
|
||||||
|
|
||||||
return IQ.createResultIQ(blockContactIQ);
|
return IQ.createResultIQ(blockContactIQ);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -117,8 +129,14 @@ public final class BlockingCommandManager extends Manager {
|
||||||
List<Jid> unblockedJids = unblockContactIQ.getJids();
|
List<Jid> unblockedJids = unblockContactIQ.getJids();
|
||||||
if (unblockedJids == null) { // remove all
|
if (unblockedJids == null) { // remove all
|
||||||
blockListCached.clear();
|
blockListCached.clear();
|
||||||
|
for (AllJidsUnblockedListener listener : allJidsUnblockedListeners) {
|
||||||
|
listener.onAllJidsUnblocked();
|
||||||
|
}
|
||||||
} else { // remove only some
|
} else { // remove only some
|
||||||
blockListCached.removeAll(unblockedJids);
|
blockListCached.removeAll(unblockedJids);
|
||||||
|
for (JidsUnblockedListener listener : jidsUnblockedListeners) {
|
||||||
|
listener.onJidsUnblocked(unblockedJids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return IQ.createResultIQ(unblockContactIQ);
|
return IQ.createResultIQ(unblockContactIQ);
|
||||||
|
@ -216,4 +234,27 @@ public final class BlockingCommandManager extends Manager {
|
||||||
connection().createStanzaCollectorAndSend(unblockContactIQ).nextResultOrThrow();
|
connection().createStanzaCollectorAndSend(unblockContactIQ).nextResultOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
||||||
|
jidsBlockedListeners.add(jidsBlockedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeJidsBlockedListener(JidsBlockedListener jidsBlockedListener) {
|
||||||
|
jidsBlockedListeners.remove(jidsBlockedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
||||||
|
jidsUnblockedListeners.add(jidsUnblockedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeJidsUnblockedListener(JidsUnblockedListener jidsUnblockedListener) {
|
||||||
|
jidsUnblockedListeners.remove(jidsUnblockedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
||||||
|
allJidsUnblockedListeners.add(allJidsUnblockedListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAllJidsUnblockedListener(AllJidsUnblockedListener allJidsUnblockedListener) {
|
||||||
|
allJidsUnblockedListeners.remove(allJidsUnblockedListener);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.blocking;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
public interface JidsBlockedListener {
|
||||||
|
|
||||||
|
void onJidsBlocked(List<Jid> blockedJids);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.blocking;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.Jid;
|
||||||
|
|
||||||
|
public interface JidsUnblockedListener {
|
||||||
|
|
||||||
|
void onJidsUnblocked(List<Jid> unblockedJids);
|
||||||
|
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.blocking.element;
|
package org.jivesoftware.smackx.blocking.element;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
@ -51,7 +52,7 @@ public class BlockContactsIQ extends IQ {
|
||||||
public BlockContactsIQ(List<Jid> jids) {
|
public BlockContactsIQ(List<Jid> jids) {
|
||||||
super(ELEMENT, NAMESPACE);
|
super(ELEMENT, NAMESPACE);
|
||||||
this.setType(Type.set);
|
this.setType(Type.set);
|
||||||
this.jids = jids;
|
this.jids = Collections.unmodifiableList(jids);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2016 Fernando Ramirez, Florian Schmaus
|
* Copyright 2016-2017 Fernando Ramirez, 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,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smackx.blocking.element;
|
package org.jivesoftware.smackx.blocking.element;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
|
@ -52,7 +53,11 @@ public class UnblockContactsIQ extends IQ {
|
||||||
public UnblockContactsIQ(List<Jid> jids) {
|
public UnblockContactsIQ(List<Jid> jids) {
|
||||||
super(ELEMENT, NAMESPACE);
|
super(ELEMENT, NAMESPACE);
|
||||||
this.setType(Type.set);
|
this.setType(Type.set);
|
||||||
this.jids = jids;
|
if (jids != null) {
|
||||||
|
this.jids = Collections.unmodifiableList(jids);
|
||||||
|
} else {
|
||||||
|
this.jids = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,9 +68,9 @@ public class UnblockContactsIQ extends IQ {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the JIDs.
|
* Get the JIDs. This may return null, which means that all JIDs should be or where unblocked.
|
||||||
*
|
*
|
||||||
* @return the list of JIDs
|
* @return the list of JIDs or <code>null</code>.
|
||||||
*/
|
*/
|
||||||
public List<Jid> getJids() {
|
public List<Jid> getJids() {
|
||||||
return jids;
|
return jids;
|
||||||
|
@ -73,14 +78,16 @@ public class UnblockContactsIQ extends IQ {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||||
xml.rightAngleBracket();
|
if (jids == null) {
|
||||||
|
xml.setEmptyElement();
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
if (jids != null) {
|
xml.rightAngleBracket();
|
||||||
for (Jid jid : jids) {
|
for (Jid jid : jids) {
|
||||||
xml.halfOpenElement("item");
|
xml.halfOpenElement("item");
|
||||||
xml.attribute("jid", jid);
|
xml.attribute("jid", jid);
|
||||||
xml.closeEmptyElement();
|
xml.closeEmptyElement();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return xml;
|
return xml;
|
||||||
|
|
|
@ -20,9 +20,9 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jivesoftware.smack.provider.IQProvider;
|
import org.jivesoftware.smack.provider.IQProvider;
|
||||||
|
import org.jivesoftware.smack.util.ParserUtils;
|
||||||
import org.jivesoftware.smackx.blocking.element.BlockContactsIQ;
|
import org.jivesoftware.smackx.blocking.element.BlockContactsIQ;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +36,7 @@ public class BlockContactsIQProvider extends IQProvider<BlockContactsIQ> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockContactsIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
public BlockContactsIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||||
List<Jid> jids = null;
|
List<Jid> jids = new ArrayList<>();
|
||||||
|
|
||||||
outerloop: while (true) {
|
outerloop: while (true) {
|
||||||
int eventType = parser.next();
|
int eventType = parser.next();
|
||||||
|
@ -45,10 +45,8 @@ public class BlockContactsIQProvider extends IQProvider<BlockContactsIQ> {
|
||||||
|
|
||||||
case XmlPullParser.START_TAG:
|
case XmlPullParser.START_TAG:
|
||||||
if (parser.getName().equals("item")) {
|
if (parser.getName().equals("item")) {
|
||||||
if (jids == null) {
|
Jid jid = ParserUtils.getJidAttribute(parser);
|
||||||
jids = new ArrayList<>();
|
jids.add(jid);
|
||||||
}
|
|
||||||
jids.add(JidCreate.from(parser.getAttributeValue("", "jid")));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ public class BookmarkedConference implements SharedBookmark {
|
||||||
this.isShared = isShared;
|
this.isShared = isShared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isShared() {
|
public boolean isShared() {
|
||||||
return isShared;
|
return isShared;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ public class BookmarkedURL implements SharedBookmark {
|
||||||
this.isShared = shared;
|
this.isShared = shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isShared() {
|
public boolean isShared() {
|
||||||
return isShared;
|
return isShared;
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,7 @@ public class Bookmarks implements PrivateData {
|
||||||
*
|
*
|
||||||
* @return the element name.
|
* @return the element name.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
@ -160,6 +161,7 @@ public class Bookmarks implements PrivateData {
|
||||||
*
|
*
|
||||||
* @return the namespace.
|
* @return the namespace.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return NAMESPACE;
|
return NAMESPACE;
|
||||||
}
|
}
|
||||||
|
@ -218,6 +220,7 @@ public class Bookmarks implements PrivateData {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
public PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||||
Bookmarks storage = new Bookmarks();
|
Bookmarks storage = new Bookmarks();
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ public abstract class InBandBytestreamListener implements BytestreamListener {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public void incomingBytestreamRequest(BytestreamRequest request) {
|
public void incomingBytestreamRequest(BytestreamRequest request) {
|
||||||
incomingBytestreamRequest((InBandBytestreamRequest) request);
|
incomingBytestreamRequest((InBandBytestreamRequest) request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
*/
|
*/
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(final XMPPConnection connection) {
|
public void connectionCreated(final XMPPConnection connection) {
|
||||||
// create the manager for this connection
|
// create the manager for this connection
|
||||||
InBandBytestreamManager.getByteStreamManager(connection);
|
InBandBytestreamManager.getByteStreamManager(connection);
|
||||||
|
@ -236,6 +237,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
*
|
*
|
||||||
* @param listener the listener to register
|
* @param listener the listener to register
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
||||||
this.allRequestListeners.add(listener);
|
this.allRequestListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
@ -246,6 +248,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
*
|
*
|
||||||
* @param listener the listener to remove
|
* @param listener the listener to remove
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
||||||
this.allRequestListeners.remove(listener);
|
this.allRequestListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
@ -268,6 +271,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
* @param listener the listener to register
|
* @param listener the listener to register
|
||||||
* @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
|
* @param initiatorJID the JID of the user that wants to establish an In-Band Bytestream
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
||||||
this.userListeners.put(initiatorJID, listener);
|
this.userListeners.put(initiatorJID, listener);
|
||||||
}
|
}
|
||||||
|
@ -277,6 +281,9 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
*
|
*
|
||||||
* @param initiatorJID the JID of the user the listener should be removed
|
* @param initiatorJID the JID of the user the listener should be removed
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
|
// TODO: Change argument to Jid in Smack 4.3.
|
||||||
|
@SuppressWarnings("CollectionIncompatibleType")
|
||||||
public void removeIncomingBytestreamListener(String initiatorJID) {
|
public void removeIncomingBytestreamListener(String initiatorJID) {
|
||||||
this.userListeners.remove(initiatorJID);
|
this.userListeners.remove(initiatorJID);
|
||||||
}
|
}
|
||||||
|
@ -402,6 +409,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
* @throws SmackException if there was no response from the server.
|
* @throws SmackException if there was no response from the server.
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public InBandBytestreamSession establishSession(Jid targetJID) throws XMPPException, SmackException, InterruptedException {
|
public InBandBytestreamSession establishSession(Jid targetJID) throws XMPPException, SmackException, InterruptedException {
|
||||||
String sessionID = getNextSessionID();
|
String sessionID = getNextSessionID();
|
||||||
return establishSession(targetJID, sessionID);
|
return establishSession(targetJID, sessionID);
|
||||||
|
@ -420,6 +428,7 @@ public final class InBandBytestreamManager implements BytestreamManager {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public InBandBytestreamSession establishSession(Jid targetJID, String sessionID)
|
public InBandBytestreamSession establishSession(Jid targetJID, String sessionID)
|
||||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
|
Open byteStreamRequest = new Open(sessionID, this.defaultBlockSize, this.stanza);
|
||||||
|
|
|
@ -50,6 +50,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
||||||
*
|
*
|
||||||
* @return the sender of the In-Band Bytestream open request
|
* @return the sender of the In-Band Bytestream open request
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Jid getFrom() {
|
public Jid getFrom() {
|
||||||
return this.byteStreamRequest.getFrom();
|
return this.byteStreamRequest.getFrom();
|
||||||
}
|
}
|
||||||
|
@ -59,6 +60,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
||||||
*
|
*
|
||||||
* @return the session ID of the In-Band Bytestream open request
|
* @return the session ID of the In-Band Bytestream open request
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getSessionID() {
|
public String getSessionID() {
|
||||||
return this.byteStreamRequest.getSessionID();
|
return this.byteStreamRequest.getSessionID();
|
||||||
}
|
}
|
||||||
|
@ -71,6 +73,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public InBandBytestreamSession accept() throws NotConnectedException, InterruptedException {
|
public InBandBytestreamSession accept() throws NotConnectedException, InterruptedException {
|
||||||
XMPPConnection connection = this.manager.getConnection();
|
XMPPConnection connection = this.manager.getConnection();
|
||||||
|
|
||||||
|
@ -92,6 +95,7 @@ public class InBandBytestreamRequest implements BytestreamRequest {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void reject() throws NotConnectedException, InterruptedException {
|
public void reject() throws NotConnectedException, InterruptedException {
|
||||||
this.manager.replyRejectPacket(this.byteStreamRequest);
|
this.manager.replyRejectPacket(this.byteStreamRequest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,18 +109,22 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() {
|
public InputStream getInputStream() {
|
||||||
return this.inputStream;
|
return this.inputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public OutputStream getOutputStream() {
|
public OutputStream getOutputStream() {
|
||||||
return this.outputStream;
|
return this.outputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getReadTimeout() {
|
public int getReadTimeout() {
|
||||||
return this.inputStream.readTimeout;
|
return this.inputStream.readTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setReadTimeout(int timeout) {
|
public void setReadTimeout(int timeout) {
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
throw new IllegalArgumentException("Timeout must be >= 0");
|
throw new IllegalArgumentException("Timeout must be >= 0");
|
||||||
|
@ -151,6 +155,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
this.closeBothStreamsEnabled = closeBothStreamsEnabled;
|
this.closeBothStreamsEnabled = closeBothStreamsEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
closeByLocal(true); // close input stream
|
closeByLocal(true); // close input stream
|
||||||
closeByLocal(false); // close output stream
|
closeByLocal(false); // close output stream
|
||||||
|
@ -224,7 +229,9 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
this.inputStream.cleanup();
|
this.inputStream.cleanup();
|
||||||
|
|
||||||
// remove session from manager
|
// remove session from manager
|
||||||
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(this);
|
// Thanks Google Error Prone for finding the bug where remove() was called with 'this' as argument. Changed
|
||||||
|
// now to remove(byteStreamRequest.getSessionID).
|
||||||
|
InBandBytestreamManager.getByteStreamManager(this.connection).getSessions().remove(byteStreamRequest.getSessionID());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -283,6 +290,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
*/
|
*/
|
||||||
protected abstract StanzaFilter getDataPacketFilter();
|
protected abstract StanzaFilter getDataPacketFilter();
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized int read() throws IOException {
|
public synchronized int read() throws IOException {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
|
|
||||||
|
@ -298,6 +306,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
return buffer[bufferPointer++] & 0xff;
|
return buffer[bufferPointer++] & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
public synchronized int read(byte[] b, int off, int len) throws IOException {
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -331,6 +340,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized int read(byte[] b) throws IOException {
|
public synchronized int read(byte[] b) throws IOException {
|
||||||
return read(b, 0, b.length);
|
return read(b, 0, b.length);
|
||||||
}
|
}
|
||||||
|
@ -405,10 +415,12 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean markSupported() {
|
public boolean markSupported() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (closeInvoked) {
|
if (closeInvoked) {
|
||||||
return;
|
return;
|
||||||
|
@ -444,11 +456,13 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
*/
|
*/
|
||||||
private class IQIBBInputStream extends IBBInputStream {
|
private class IQIBBInputStream extends IBBInputStream {
|
||||||
|
|
||||||
|
@Override
|
||||||
protected StanzaListener getDataPacketListener() {
|
protected StanzaListener getDataPacketListener() {
|
||||||
return new StanzaListener() {
|
return new StanzaListener() {
|
||||||
|
|
||||||
private long lastSequence = -1;
|
private long lastSequence = -1;
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
|
public void processStanza(Stanza packet) throws NotConnectedException, InterruptedException {
|
||||||
// get data packet extension
|
// get data packet extension
|
||||||
DataPacketExtension data = ((Data) packet).getDataPacketExtension();
|
DataPacketExtension data = ((Data) packet).getDataPacketExtension();
|
||||||
|
@ -491,6 +505,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected StanzaFilter getDataPacketFilter() {
|
protected StanzaFilter getDataPacketFilter() {
|
||||||
/*
|
/*
|
||||||
* filter all IQ stanzas having type 'SET' (represented by Data class), containing a
|
* filter all IQ stanzas having type 'SET' (represented by Data class), containing a
|
||||||
|
@ -507,9 +522,11 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
*/
|
*/
|
||||||
private class MessageIBBInputStream extends IBBInputStream {
|
private class MessageIBBInputStream extends IBBInputStream {
|
||||||
|
|
||||||
|
@Override
|
||||||
protected StanzaListener getDataPacketListener() {
|
protected StanzaListener getDataPacketListener() {
|
||||||
return new StanzaListener() {
|
return new StanzaListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
// get data packet extension
|
// get data packet extension
|
||||||
DataPacketExtension data = (DataPacketExtension) packet.getExtension(
|
DataPacketExtension data = (DataPacketExtension) packet.getExtension(
|
||||||
|
@ -555,6 +572,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
*/
|
*/
|
||||||
private class IBBDataPacketFilter implements StanzaFilter {
|
private class IBBDataPacketFilter implements StanzaFilter {
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean accept(Stanza packet) {
|
public boolean accept(Stanza packet) {
|
||||||
// sender equals remote peer
|
// sender equals remote peer
|
||||||
if (!packet.getFrom().equals(remoteJID)) {
|
if (!packet.getFrom().equals(remoteJID)) {
|
||||||
|
@ -619,6 +637,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
*/
|
*/
|
||||||
protected abstract void writeToXML(DataPacketExtension data) throws IOException, NotConnectedException, InterruptedException;
|
protected abstract void writeToXML(DataPacketExtension data) throws IOException, NotConnectedException, InterruptedException;
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void write(int b) throws IOException {
|
public synchronized void write(int b) throws IOException {
|
||||||
if (this.isClosed) {
|
if (this.isClosed) {
|
||||||
throw new IOException("Stream is closed");
|
throw new IOException("Stream is closed");
|
||||||
|
@ -632,6 +651,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
buffer[bufferPointer++] = (byte) b;
|
buffer[bufferPointer++] = (byte) b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void write(byte[] b, int off, int len) throws IOException {
|
public synchronized void write(byte[] b, int off, int len) throws IOException {
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -662,6 +682,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void write(byte[] b) throws IOException {
|
public synchronized void write(byte[] b) throws IOException {
|
||||||
write(b, 0, b.length);
|
write(b, 0, b.length);
|
||||||
}
|
}
|
||||||
|
@ -698,6 +719,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
bufferPointer += len - available;
|
bufferPointer += len - available;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public synchronized void flush() throws IOException {
|
public synchronized void flush() throws IOException {
|
||||||
if (this.isClosed) {
|
if (this.isClosed) {
|
||||||
throw new IOException("Stream is closed");
|
throw new IOException("Stream is closed");
|
||||||
|
@ -735,6 +757,7 @@ public class InBandBytestreamSession implements BytestreamSession {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
if (isClosed) {
|
if (isClosed) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -66,6 +66,7 @@ class InitiationListener extends AbstractIqRequestHandler {
|
||||||
public IQ handleIQRequest(final IQ packet) {
|
public IQ handleIQRequest(final IQ packet) {
|
||||||
initiationListenerExecutor.execute(new Runnable() {
|
initiationListenerExecutor.execute(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
processRequest(packet);
|
processRequest(packet);
|
||||||
|
|
|
@ -126,10 +126,12 @@ public class DataPacketExtension implements ExtensionElement {
|
||||||
return this.decodedData;
|
return this.decodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return NAMESPACE;
|
return NAMESPACE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,7 @@ final class InitiationListener extends AbstractIqRequestHandler {
|
||||||
public IQ handleIQRequest(final IQ packet) {
|
public IQ handleIQRequest(final IQ packet) {
|
||||||
initiationListenerExecutor.execute(new Runnable() {
|
initiationListenerExecutor.execute(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
processRequest(packet);
|
processRequest(packet);
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.jivesoftware.smackx.bytestreams.BytestreamRequest;
|
||||||
*/
|
*/
|
||||||
public abstract class Socks5BytestreamListener implements BytestreamListener {
|
public abstract class Socks5BytestreamListener implements BytestreamListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void incomingBytestreamRequest(BytestreamRequest request) {
|
public void incomingBytestreamRequest(BytestreamRequest request) {
|
||||||
incomingBytestreamRequest((Socks5BytestreamRequest) request);
|
incomingBytestreamRequest((Socks5BytestreamRequest) request);
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,6 +98,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void connectionCreated(final XMPPConnection connection) {
|
public void connectionCreated(final XMPPConnection connection) {
|
||||||
// create the manager for this connection
|
// create the manager for this connection
|
||||||
Socks5BytestreamManager.getBytestreamManager(connection);
|
Socks5BytestreamManager.getBytestreamManager(connection);
|
||||||
|
@ -198,6 +199,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
*
|
*
|
||||||
* @param listener the listener to register
|
* @param listener the listener to register
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
public void addIncomingBytestreamListener(BytestreamListener listener) {
|
||||||
this.allRequestListeners.add(listener);
|
this.allRequestListeners.add(listener);
|
||||||
}
|
}
|
||||||
|
@ -208,6 +210,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
*
|
*
|
||||||
* @param listener the listener to remove
|
* @param listener the listener to remove
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
public void removeIncomingBytestreamListener(BytestreamListener listener) {
|
||||||
this.allRequestListeners.remove(listener);
|
this.allRequestListeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
@ -230,6 +233,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
* @param listener the listener to register
|
* @param listener the listener to register
|
||||||
* @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
|
* @param initiatorJID the JID of the user that wants to establish a SOCKS5 Bytestream
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
public void addIncomingBytestreamListener(BytestreamListener listener, Jid initiatorJID) {
|
||||||
this.userListeners.put(initiatorJID, listener);
|
this.userListeners.put(initiatorJID, listener);
|
||||||
}
|
}
|
||||||
|
@ -239,6 +243,9 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
*
|
*
|
||||||
* @param initiatorJID the JID of the user the listener should be removed
|
* @param initiatorJID the JID of the user the listener should be removed
|
||||||
*/
|
*/
|
||||||
|
// TODO: Change parameter to Jid in Smack 4.3.
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("CollectionIncompatibleType")
|
||||||
public void removeIncomingBytestreamListener(String initiatorJID) {
|
public void removeIncomingBytestreamListener(String initiatorJID) {
|
||||||
this.userListeners.remove(initiatorJID);
|
this.userListeners.remove(initiatorJID);
|
||||||
}
|
}
|
||||||
|
@ -386,6 +393,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
* @throws InterruptedException if the current thread was interrupted while waiting
|
* @throws InterruptedException if the current thread was interrupted while waiting
|
||||||
* @throws SmackException if there was no response from the server.
|
* @throws SmackException if there was no response from the server.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Socks5BytestreamSession establishSession(Jid targetJID) throws XMPPException,
|
public Socks5BytestreamSession establishSession(Jid targetJID) throws XMPPException,
|
||||||
IOException, InterruptedException, SmackException {
|
IOException, InterruptedException, SmackException {
|
||||||
String sessionID = getNextSessionID();
|
String sessionID = getNextSessionID();
|
||||||
|
@ -405,6 +413,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
||||||
* @throws SmackException if the target does not support SOCKS5.
|
* @throws SmackException if the target does not support SOCKS5.
|
||||||
* @throws XMPPException
|
* @throws XMPPException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Socks5BytestreamSession establishSession(Jid targetJID, String sessionID)
|
public Socks5BytestreamSession establishSession(Jid targetJID, String sessionID)
|
||||||
throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{
|
throws IOException, InterruptedException, NoResponseException, SmackException, XMPPException{
|
||||||
XMPPConnection connection = connection();
|
XMPPConnection connection = connection();
|
||||||
|
|
|
@ -170,6 +170,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
||||||
*
|
*
|
||||||
* @return the sender of the SOCKS5 Bytestream initialization request.
|
* @return the sender of the SOCKS5 Bytestream initialization request.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Jid getFrom() {
|
public Jid getFrom() {
|
||||||
return this.bytestreamRequest.getFrom();
|
return this.bytestreamRequest.getFrom();
|
||||||
}
|
}
|
||||||
|
@ -179,6 +180,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
||||||
*
|
*
|
||||||
* @return the session ID of the SOCKS5 Bytestream initialization request.
|
* @return the session ID of the SOCKS5 Bytestream initialization request.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public String getSessionID() {
|
public String getSessionID() {
|
||||||
return this.bytestreamRequest.getSessionID();
|
return this.bytestreamRequest.getSessionID();
|
||||||
}
|
}
|
||||||
|
@ -195,6 +197,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
* @throws SmackException
|
* @throws SmackException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException {
|
public Socks5BytestreamSession accept() throws InterruptedException, XMPPErrorException, SmackException {
|
||||||
Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
|
Collection<StreamHost> streamHosts = this.bytestreamRequest.getStreamHosts();
|
||||||
|
|
||||||
|
@ -264,6 +267,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void reject() throws NotConnectedException, InterruptedException {
|
public void reject() throws NotConnectedException, InterruptedException {
|
||||||
this.manager.replyRejectPacket(this.bytestreamRequest);
|
this.manager.replyRejectPacket(this.bytestreamRequest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,14 +64,17 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
||||||
return !this.isDirect;
|
return !this.isDirect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public InputStream getInputStream() throws IOException {
|
public InputStream getInputStream() throws IOException {
|
||||||
return this.socket.getInputStream();
|
return this.socket.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public OutputStream getOutputStream() throws IOException {
|
public OutputStream getOutputStream() throws IOException {
|
||||||
return this.socket.getOutputStream();
|
return this.socket.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int getReadTimeout() throws IOException {
|
public int getReadTimeout() throws IOException {
|
||||||
try {
|
try {
|
||||||
return this.socket.getSoTimeout();
|
return this.socket.getSoTimeout();
|
||||||
|
@ -81,6 +84,7 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setReadTimeout(int timeout) throws IOException {
|
public void setReadTimeout(int timeout) throws IOException {
|
||||||
try {
|
try {
|
||||||
this.socket.setSoTimeout(timeout);
|
this.socket.setSoTimeout(timeout);
|
||||||
|
@ -90,6 +94,7 @@ public class Socks5BytestreamSession implements BytestreamSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
this.socket.close();
|
this.socket.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.bytestreams.socks5;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
|
@ -34,6 +35,7 @@ import java.util.logging.Logger;
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPException;
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
|
import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -82,6 +84,7 @@ class Socks5Client {
|
||||||
// wrap connecting in future for timeout
|
// wrap connecting in future for timeout
|
||||||
FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
|
FutureTask<Socket> futureTask = new FutureTask<Socket>(new Callable<Socket>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
public Socket call() throws IOException, SmackException {
|
public Socket call() throws IOException, SmackException {
|
||||||
|
|
||||||
// initialize socket
|
// initialize socket
|
||||||
|
@ -199,7 +202,13 @@ class Socks5Client {
|
||||||
* @return SOCKS5 connection request message
|
* @return SOCKS5 connection request message
|
||||||
*/
|
*/
|
||||||
private byte[] createSocks5ConnectRequest() {
|
private byte[] createSocks5ConnectRequest() {
|
||||||
byte[] addr = this.digest.getBytes();
|
byte[] addr;
|
||||||
|
try {
|
||||||
|
addr = digest.getBytes(StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
|
||||||
byte[] data = new byte[7 + addr.length];
|
byte[] data = new byte[7 + addr.length];
|
||||||
data[0] = (byte) 0x05; // version (SOCKS5)
|
data[0] = (byte) 0x05; // version (SOCKS5)
|
||||||
|
|
|
@ -69,6 +69,7 @@ class Socks5ClientForInitiator extends Socks5Client {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Socket getSocket(int timeout) throws IOException, InterruptedException,
|
public Socket getSocket(int timeout) throws IOException, InterruptedException,
|
||||||
TimeoutException, XMPPException, SmackException {
|
TimeoutException, XMPPException, SmackException {
|
||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
|
|
|
@ -38,6 +38,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by
|
* The Socks5Proxy class represents a local SOCKS5 proxy server. It can be enabled/disabled by
|
||||||
|
@ -381,6 +382,7 @@ public final class Socks5Proxy {
|
||||||
*/
|
*/
|
||||||
private class Socks5ServerProcess implements Runnable {
|
private class Socks5ServerProcess implements Runnable {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
Socket socket = null;
|
Socket socket = null;
|
||||||
|
@ -470,7 +472,7 @@ public final class Socks5Proxy {
|
||||||
byte[] connectionRequest = Socks5Utils.receiveSocks5Message(in);
|
byte[] connectionRequest = Socks5Utils.receiveSocks5Message(in);
|
||||||
|
|
||||||
// extract digest
|
// extract digest
|
||||||
String responseDigest = new String(connectionRequest, 5, connectionRequest[4]);
|
String responseDigest = new String(connectionRequest, 5, connectionRequest[4], StringUtils.UTF8);
|
||||||
|
|
||||||
// return error if digest is not allowed
|
// return error if digest is not allowed
|
||||||
if (!Socks5Proxy.this.allowedConnections.contains(responseDigest)) {
|
if (!Socks5Proxy.this.allowedConnections.contains(responseDigest)) {
|
||||||
|
|
|
@ -317,6 +317,7 @@ public class Bytestream extends IQ {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENTNAME;
|
return ELEMENTNAME;
|
||||||
}
|
}
|
||||||
|
@ -366,6 +367,7 @@ public class Bytestream extends IQ {
|
||||||
return JID;
|
return JID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENTNAME;
|
return ELEMENTNAME;
|
||||||
}
|
}
|
||||||
|
@ -408,6 +410,7 @@ public class Bytestream extends IQ {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENTNAME;
|
return ELEMENTNAME;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
|
@ -113,6 +114,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||||
|
@Override
|
||||||
public void connectionCreated(XMPPConnection connection) {
|
public void connectionCreated(XMPPConnection connection) {
|
||||||
getInstanceFor(connection);
|
getInstanceFor(connection);
|
||||||
}
|
}
|
||||||
|
@ -346,6 +348,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
// XEP-0115 specifies that a client SHOULD include entity capabilities
|
// XEP-0115 specifies that a client SHOULD include entity capabilities
|
||||||
// with every presence notification it sends.
|
// with every presence notification it sends.
|
||||||
StanzaListener packetInterceptor = new StanzaListener() {
|
StanzaListener packetInterceptor = new StanzaListener() {
|
||||||
|
@Override
|
||||||
public void processStanza(Stanza packet) {
|
public void processStanza(Stanza packet) {
|
||||||
if (!entityCapsEnabled) {
|
if (!entityCapsEnabled) {
|
||||||
// Be sure to not send stanzas with the caps extension if it's not enabled
|
// Be sure to not send stanzas with the caps extension if it's not enabled
|
||||||
|
@ -403,7 +406,11 @@ public final class EntityCapsManager extends Manager {
|
||||||
* @param user
|
* @param user
|
||||||
* the user (Full JID)
|
* the user (Full JID)
|
||||||
*/
|
*/
|
||||||
|
// TODO: Change parameter type to Jid in Smack 4.3.
|
||||||
|
@SuppressWarnings("CollectionIncompatibleType")
|
||||||
public static void removeUserCapsNode(String user) {
|
public static void removeUserCapsNode(String user) {
|
||||||
|
// While JID_TO_NODEVER_CHACHE has the generic types <Jid, NodeVerHash>, it is ok to call remove with String
|
||||||
|
// arguments, since the same Jid and String representations would be equal and have the same hash code.
|
||||||
JID_TO_NODEVER_CACHE.remove(user);
|
JID_TO_NODEVER_CACHE.remove(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,6 +665,7 @@ public final class EntityCapsManager extends Manager {
|
||||||
// XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
|
// XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e.,
|
||||||
// by the XML character data of the <value/> element).
|
// by the XML character data of the <value/> element).
|
||||||
SortedSet<FormField> fs = new TreeSet<FormField>(new Comparator<FormField>() {
|
SortedSet<FormField> fs = new TreeSet<FormField>(new Comparator<FormField>() {
|
||||||
|
@Override
|
||||||
public int compare(FormField f1, FormField f2) {
|
public int compare(FormField f1, FormField f2) {
|
||||||
return f1.getVariable().compareTo(f2.getVariable());
|
return f1.getVariable().compareTo(f2.getVariable());
|
||||||
}
|
}
|
||||||
|
@ -701,9 +709,16 @@ public final class EntityCapsManager extends Manager {
|
||||||
// encoded using Base64 as specified in Section 4 of RFC 4648
|
// encoded using Base64 as specified in Section 4 of RFC 4648
|
||||||
// (note: the Base64 output MUST NOT include whitespace and MUST set
|
// (note: the Base64 output MUST NOT include whitespace and MUST set
|
||||||
// padding bits to zero).
|
// padding bits to zero).
|
||||||
|
byte[] bytes;
|
||||||
|
try {
|
||||||
|
bytes = sb.toString().getBytes(StringUtils.UTF8);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
byte[] digest;
|
byte[] digest;
|
||||||
synchronized(md) {
|
synchronized(md) {
|
||||||
digest = md.digest(sb.toString().getBytes());
|
digest = md.digest(bytes);
|
||||||
}
|
}
|
||||||
String version = Base64.encodeToString(digest);
|
String version = Base64.encodeToString(digest);
|
||||||
return new CapsVersionAndHash(version, hash);
|
return new CapsVersionAndHash(version, hash);
|
||||||
|
|
|
@ -35,10 +35,12 @@ public class CapsExtension implements ExtensionElement {
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getElementName() {
|
public String getElementName() {
|
||||||
return ELEMENT;
|
return ELEMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public String getNamespace() {
|
public String getNamespace() {
|
||||||
return NAMESPACE;
|
return NAMESPACE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
public class CapsExtensionProvider extends ExtensionElementProvider<CapsExtension> {
|
public class CapsExtensionProvider extends ExtensionElementProvider<CapsExtension> {
|
||||||
|
|
||||||
|
@Override
|
||||||
public CapsExtension parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException,
|
public CapsExtension parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException,
|
||||||
SmackException {
|
SmackException {
|
||||||
String hash = null;
|
String hash = null;
|
||||||
|
|
|
@ -119,6 +119,7 @@ public final class ChatStateManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
@ -129,6 +130,7 @@ public final class ChatStateManager extends Manager {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return connection().hashCode();
|
return connection().hashCode();
|
||||||
}
|
}
|
||||||
|
@ -164,12 +166,14 @@ public final class ChatStateManager extends Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IncomingMessageInterceptor implements ChatManagerListener, ChatMessageListener {
|
private static class IncomingMessageInterceptor implements ChatManagerListener, ChatMessageListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
public void chatCreated(final org.jivesoftware.smack.chat.Chat chat, boolean createdLocally) {
|
public void chatCreated(final org.jivesoftware.smack.chat.Chat chat, boolean createdLocally) {
|
||||||
chat.addMessageListener(this);
|
chat.addMessageListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void processMessage(org.jivesoftware.smack.chat.Chat chat, Message message) {
|
public void processMessage(org.jivesoftware.smack.chat.Chat chat, Message message) {
|
||||||
ExtensionElement extension = message.getExtension(NAMESPACE);
|
ExtensionElement extension = message.getExtension(NAMESPACE);
|
||||||
if (extension == null) {
|
if (extension == null) {
|
||||||
|
|
|
@ -19,9 +19,7 @@ package org.jivesoftware.smackx.chatstates.packet;
|
||||||
|
|
||||||
import org.jivesoftware.smackx.chatstates.ChatState;
|
import org.jivesoftware.smackx.chatstates.ChatState;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
|
||||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a chat state which is an extension to message packets which is used to indicate
|
* Represents a chat state which is an extension to message packets which is used to indicate
|
||||||
|
@ -66,18 +64,4 @@ public class ChatStateExtension implements ExtensionElement {
|
||||||
return xml;
|
return xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Provider extends ExtensionElementProvider<ChatStateExtension> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChatStateExtension parse(XmlPullParser parser, int initialDepth) {
|
|
||||||
ChatState state;
|
|
||||||
try {
|
|
||||||
state = ChatState.valueOf(parser.getName());
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
state = ChatState.active;
|
|
||||||
}
|
|
||||||
return new ChatStateExtension(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.chatstates.provider;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||||
|
import org.jivesoftware.smackx.chatstates.ChatState;
|
||||||
|
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
public class ChatStateExtensionProvider extends ExtensionElementProvider<ChatStateExtension> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChatStateExtension parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||||
|
String chatStateString = parser.getName();
|
||||||
|
ChatState state = ChatState.valueOf(chatStateString);
|
||||||
|
|
||||||
|
return new ChatStateExtension(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provider classes for Chat State Notifications (XEP-0085).
|
||||||
|
*/
|
||||||
|
package org.jivesoftware.smackx.chatstates.provider;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue