mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
Smack 4.1.4
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQF8BAABCgBmBQJV9nAlXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25zLm9w ZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQxMzU3QjAxODY1QjI1MDNDMTg0NTNEMjA4 Q0FDMkE5Njc4NTQ4RTM1AAoJEIysKpZ4VI41sFEIAJlfRspk6S5ymNc4w7u/FT1w MpHT/cxqIQIBU9J5dYqeW6Y8O6VuUeknCmZBEv7dIVHroTmvfosMauAyRZJXWeeL FQQTBqDJszYdM88x/d5X6d25lCEBdQkdDh2a5s9AIy9RH0iXE74AypuikbroK+VC zI3wRPUFq7WnARtmiP2NalSgSNv5ToeicBO+JSniQ+O52ZAlP2FSDfi4uzPPigdP Ip/V3eF4Bp0YZimcxAnWdnMU+ciVLClRYKgD3+qTEoic7dx3dzeTyrk1NoLRgQl9 mfcNXBgUScHZAoSIkR0QiUx9ktPCJ950qa+XtW3B8NtDOZkXegUL/a8ukQAuz+k= =qMsC -----END PGP SIGNATURE----- Merge tag '4.1.4' Smack 4.1.4
This commit is contained in:
commit
04a0004035
10 changed files with 96 additions and 12 deletions
|
@ -141,6 +141,35 @@ hr {
|
||||||
|
|
||||||
<div id="pageBody">
|
<div id="pageBody">
|
||||||
|
|
||||||
|
|
||||||
|
<h2>4.1.4 -- <span style="font-weight: normal;">2015-09-14</span></h2>
|
||||||
|
|
||||||
|
<h2> Bug
|
||||||
|
</h2>
|
||||||
|
<ul>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-688'>SMACK-688</a>] - Reset carbons state if session got not resumed or cleanly disconnected
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-689'>SMACK-689</a>] - PEPPubSub creates malformed XML
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-693'>SMACK-693</a>] - MultiUserChat's UserStatusListener is not getting triggered
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-695'>SMACK-695</a>] - JSON and GCM parser does an erroneous extra next()
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-697'>SMACK-697</a>] - PrivacyListManager should handle the case where not default and active list are currently set
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2> Improvement
|
||||||
|
</h2>
|
||||||
|
<ul>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-686'>SMACK-686</a>] - Provide a hint that connect() needs to be called prior login() in NotConnectedException
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-687'>SMACK-687</a>] - Update to jxmpp 0.4.2
|
||||||
|
</li>
|
||||||
|
<li>[<a href='https://igniterealtime.org/issues/browse/SMACK-696'>SMACK-696</a>] - Drop stream state after stream error
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<h2>4.1.3 -- <span style="font-weight: normal;">2015-07-15</span></h2>
|
<h2>4.1.3 -- <span style="font-weight: normal;">2015-07-15</span></h2>
|
||||||
|
|
||||||
<h2> Bug
|
<h2> Bug
|
||||||
|
|
|
@ -459,7 +459,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
if (!config.allowNullOrEmptyUsername) {
|
if (!config.allowNullOrEmptyUsername) {
|
||||||
StringUtils.requireNotNullOrEmpty(username, "Username must not be null or empty");
|
StringUtils.requireNotNullOrEmpty(username, "Username must not be null or empty");
|
||||||
}
|
}
|
||||||
throwNotConnectedExceptionIfAppropriate();
|
throwNotConnectedExceptionIfAppropriate("Did you call connect() before login()?");
|
||||||
throwAlreadyLoggedInExceptionIfAppropriate();
|
throwAlreadyLoggedInExceptionIfAppropriate();
|
||||||
usedUsername = username != null ? username.toString() : null;
|
usedUsername = username != null ? username.toString() : null;
|
||||||
usedPassword = password;
|
usedPassword = password;
|
||||||
|
@ -604,8 +604,12 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void throwNotConnectedExceptionIfAppropriate() throws NotConnectedException {
|
protected void throwNotConnectedExceptionIfAppropriate() throws NotConnectedException {
|
||||||
|
throwNotConnectedExceptionIfAppropriate(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void throwNotConnectedExceptionIfAppropriate(String optionalHint) throws NotConnectedException {
|
||||||
if (!isConnected()) {
|
if (!isConnected()) {
|
||||||
throw new NotConnectedException();
|
throw new NotConnectedException(optionalHint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,12 @@ public class SmackException extends Exception {
|
||||||
private static final long serialVersionUID = 9197980400776001173L;
|
private static final long serialVersionUID = 9197980400776001173L;
|
||||||
|
|
||||||
public NotConnectedException() {
|
public NotConnectedException() {
|
||||||
super("Client is not, or no longer, connected");
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotConnectedException(String optionalHint) {
|
||||||
|
super("Client is not, or no longer, connected."
|
||||||
|
+ (optionalHint != null ? ' ' + optionalHint : ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotConnectedException(XMPPConnection connection, String details) {
|
public NotConnectedException(XMPPConnection connection, String details) {
|
||||||
|
|
|
@ -297,7 +297,8 @@ public class PacketParserUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the textual content of an element as String.
|
* Returns the textual content of an element as String. After this method returns the parser
|
||||||
|
* position will be END_TAG, following the established pull parser calling convention.
|
||||||
* <p>
|
* <p>
|
||||||
* The parser must be positioned on a START_TAG of an element which MUST NOT contain Mixed
|
* The parser must be positioned on a START_TAG of an element which MUST NOT contain Mixed
|
||||||
* Content (as defined in XML 3.2.2), or else an XmlPullParserException will be thrown.
|
* Content (as defined in XML 3.2.2), or else an XmlPullParserException will be thrown.
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import org.jivesoftware.smack.ExceptionCallback;
|
import org.jivesoftware.smack.ExceptionCallback;
|
||||||
|
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
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;
|
||||||
|
@ -66,6 +67,22 @@ public final class CarbonManager extends Manager {
|
||||||
super(connection);
|
super(connection);
|
||||||
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||||
sdm.addFeature(CarbonExtension.NAMESPACE);
|
sdm.addFeature(CarbonExtension.NAMESPACE);
|
||||||
|
connection.addConnectionListener(new AbstractConnectionListener() {
|
||||||
|
@Override
|
||||||
|
public void connectionClosed() {
|
||||||
|
// Reset the state if the connection was cleanly closed. Note that this is not strictly necessary,
|
||||||
|
// because we also reset in authenticated() if the stream got not resumed, but for maximum correctness,
|
||||||
|
// also reset here.
|
||||||
|
enabled_state = false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||||
|
if (!resumed) {
|
||||||
|
// Non-resumed XMPP sessions always start with disabled carbons
|
||||||
|
enabled_state = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright © 2014 Florian Schmaus
|
* Copyright © 2014-2015 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.
|
||||||
|
@ -31,7 +31,6 @@ public abstract class AbstractJsonExtensionProvider extends ExtensionElementProv
|
||||||
public AbstractJsonPacketExtension parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException,
|
public AbstractJsonPacketExtension parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException,
|
||||||
IOException, SmackException {
|
IOException, SmackException {
|
||||||
String json = PacketParserUtils.parseElementText(parser);
|
String json = PacketParserUtils.parseElementText(parser);
|
||||||
parser.next();
|
|
||||||
return from(json);
|
return from(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ public class MultiUserChat {
|
||||||
Presence oldPresence = occupantsMap.put(from, presence);
|
Presence oldPresence = occupantsMap.put(from, presence);
|
||||||
if (oldPresence != null) {
|
if (oldPresence != null) {
|
||||||
// Get the previous occupant's affiliation & role
|
// Get the previous occupant's affiliation & role
|
||||||
MUCUser mucExtension = MUCUser.from(packet);
|
MUCUser mucExtension = MUCUser.from(oldPresence);
|
||||||
MUCAffiliation oldAffiliation = mucExtension.getItem().getAffiliation();
|
MUCAffiliation oldAffiliation = mucExtension.getItem().getAffiliation();
|
||||||
MUCRole oldRole = mucExtension.getItem().getRole();
|
MUCRole oldRole = mucExtension.getItem().getRole();
|
||||||
// Get the new occupant's affiliation & role
|
// Get the new occupant's affiliation & role
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
||||||
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
|
||||||
import org.jivesoftware.smack.packet.IQ;
|
import org.jivesoftware.smack.packet.IQ;
|
||||||
import org.jivesoftware.smack.packet.Stanza;
|
import org.jivesoftware.smack.packet.Stanza;
|
||||||
|
import org.jivesoftware.smack.util.StringUtils;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
import org.jivesoftware.smackx.privacy.filter.SetActiveListFilter;
|
import org.jivesoftware.smackx.privacy.filter.SetActiveListFilter;
|
||||||
import org.jivesoftware.smackx.privacy.filter.SetDefaultListFilter;
|
import org.jivesoftware.smackx.privacy.filter.SetDefaultListFilter;
|
||||||
|
@ -270,7 +271,7 @@ public final class PrivacyListManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answer the active privacy list.
|
* Answer the active privacy list. Returns <code>null</code> if there is no active list.
|
||||||
*
|
*
|
||||||
* @return the privacy list of the active list.
|
* @return the privacy list of the active list.
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
|
@ -281,6 +282,9 @@ public final class PrivacyListManager extends Manager {
|
||||||
public PrivacyList getActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
public PrivacyList getActiveList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
Privacy privacyAnswer = this.getPrivacyWithListNames();
|
Privacy privacyAnswer = this.getPrivacyWithListNames();
|
||||||
String listName = privacyAnswer.getActiveName();
|
String listName = privacyAnswer.getActiveName();
|
||||||
|
if (StringUtils.isNullOrEmpty(listName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
boolean isDefaultAndActive = listName != null && listName.equals(privacyAnswer.getDefaultName());
|
boolean isDefaultAndActive = listName != null && listName.equals(privacyAnswer.getDefaultName());
|
||||||
return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
|
return new PrivacyList(true, isDefaultAndActive, listName, getPrivacyListItems(listName));
|
||||||
}
|
}
|
||||||
|
@ -303,7 +307,7 @@ public final class PrivacyListManager extends Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Answer the default privacy list.
|
* Answer the default privacy list. Returns <code>null</code> if there is no default list.
|
||||||
*
|
*
|
||||||
* @return the privacy list of the default list.
|
* @return the privacy list of the default list.
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
|
@ -314,7 +318,10 @@ public final class PrivacyListManager extends Manager {
|
||||||
public PrivacyList getDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
public PrivacyList getDefaultList() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
Privacy privacyAnswer = this.getPrivacyWithListNames();
|
Privacy privacyAnswer = this.getPrivacyWithListNames();
|
||||||
String listName = privacyAnswer.getDefaultName();
|
String listName = privacyAnswer.getDefaultName();
|
||||||
boolean isDefaultAndActive = listName != null && listName.equals(privacyAnswer.getActiveName());
|
if (StringUtils.isNullOrEmpty(listName)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
boolean isDefaultAndActive = listName.equals(privacyAnswer.getActiveName());
|
||||||
return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
|
return new PrivacyList(isDefaultAndActive, true, listName, getPrivacyListItems(listName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +375,7 @@ public final class PrivacyListManager extends Manager {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
private List<PrivacyItem> getPrivacyListItems(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
private List<PrivacyItem> getPrivacyListItems(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
assert StringUtils.isNotEmpty(listName);
|
||||||
// The request of the list is an privacy message with an empty list
|
// The request of the list is an privacy message with an empty list
|
||||||
Privacy request = new Privacy();
|
Privacy request = new Privacy();
|
||||||
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
request.setPrivacyList(listName, new ArrayList<PrivacyItem>());
|
||||||
|
@ -389,6 +397,7 @@ public final class PrivacyListManager extends Manager {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
*/
|
*/
|
||||||
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
public PrivacyList getPrivacyList(String listName) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
listName = StringUtils.requireNotNullOrEmpty(listName, "List name must not be null");
|
||||||
return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
|
return new PrivacyList(false, false, listName, getPrivacyListItems(listName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1290,7 +1290,7 @@ public final class Roster extends Manager {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isLoaded()) {
|
if (!isLoaded() && rosterLoadedAtLogin) {
|
||||||
LOGGER.warning("Roster not loaded while processing presence stanza");
|
LOGGER.warning("Roster not loaded while processing presence stanza");
|
||||||
}
|
}
|
||||||
Presence presence = (Presence) packet;
|
Presence presence = (Presence) packet;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jivesoftware.smack.tcp;
|
package org.jivesoftware.smack.tcp;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.AbstractConnectionListener;
|
||||||
import org.jivesoftware.smack.AbstractXMPPConnection;
|
import org.jivesoftware.smack.AbstractXMPPConnection;
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||||
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
|
||||||
|
@ -299,6 +300,14 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
public XMPPTCPConnection(XMPPTCPConnectionConfiguration config) {
|
public XMPPTCPConnection(XMPPTCPConnectionConfiguration config) {
|
||||||
super(config);
|
super(config);
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
addConnectionListener(new AbstractConnectionListener() {
|
||||||
|
@Override
|
||||||
|
public void connectionClosedOnError(Exception e) {
|
||||||
|
if (e instanceof XMPPException.StreamErrorException) {
|
||||||
|
dropSmState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -398,7 +407,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
// connection instance though). This is used in writePackets to decide if stanzas should
|
// connection instance though). This is used in writePackets to decide if stanzas should
|
||||||
// be added to the unacknowledged stanzas queue, because they have to be added right
|
// be added to the unacknowledged stanzas queue, because they have to be added right
|
||||||
// after the 'enable' stream element has been sent.
|
// after the 'enable' stream element has been sent.
|
||||||
unacknowledgedStanzas = null;
|
dropSmState();
|
||||||
}
|
}
|
||||||
if (isSmAvailable() && useSm) {
|
if (isSmAvailable() && useSm) {
|
||||||
// Remove what is maybe left from previously stream managed sessions
|
// Remove what is maybe left from previously stream managed sessions
|
||||||
|
@ -1715,6 +1724,17 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop the stream management state. Sets {@link #smSessionId} and
|
||||||
|
* {@link #unacknowledgedStanzas} to <code>null</code>.
|
||||||
|
*/
|
||||||
|
private void dropSmState() {
|
||||||
|
// clientHandledCount and serverHandledCount will be reset on <enable/> and <enabled/>
|
||||||
|
// respective. No need to reset them here.
|
||||||
|
smSessionId = null;
|
||||||
|
unacknowledgedStanzas = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the maximum resumption time in seconds after which a managed stream can be resumed.
|
* Get the maximum resumption time in seconds after which a managed stream can be resumed.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
Loading…
Reference in a new issue