Smack 4.3.1

-----BEGIN PGP SIGNATURE-----
 
 iQGTBAABCgB9FiEEl3UFnzoh3OFr5PuuIjmn6PWFIFIFAlvDIBdfFIAAAAAALgAo
 aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDk3
 NzUwNTlGM0EyMURDRTE2QkU0RkJBRTIyMzlBN0U4RjU4NTIwNTIACgkQIjmn6PWF
 IFKObAgApvEwstvSXhgzlrA46DM6fXezbPEnO1rh8rCPJEAsmfBSnyINSuuhelzw
 zN8L7GAU0jDeuDivxA12vQx5QB8wuCHKgc5pXDKNRi9eUdsyDUMKswcbMMAJWDvq
 I3bm7TOC1D9ZWmfhGmqfulrsVD1Q0wh+P2A1/CWVR5ZZUB5S4fESFZUrnCfJmeXe
 f+INXUiui3otAF6nPxKm782rSfHWvA32i4Obnagh3oPX/c9R7Ftb78Wukrsbaqfg
 +a5iTlBJXLG75/Yozq+JqmWlUvEKv7le0vkF5fF+oc76H4p1U1wqQyIMei/Pwaer
 H/SyMqLPzCiwpUHiunpWD13e5kkeLw==
 =47on
 -----END PGP SIGNATURE-----

Merge tag '4.3.1'

Smack 4.3.1
This commit is contained in:
Florian Schmaus 2018-10-14 14:31:31 +02:00
commit ab120691cb
8 changed files with 82 additions and 10 deletions

View File

@ -141,6 +141,24 @@ hr {
<div id="pageBody"> <div id="pageBody">
<h2>4.3.1 -- <span style="font-weight: normal;">2018-10-14</span></h2>
<h2> Bug
</h2>
<ul>
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-833'>SMACK-833</a>] - XMLUtil.prettyFormatXml() throws on some Android devices
</li>
</ul>
<h2> Improvement
</h2>
<ul>
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-829'>SMACK-829</a>] - Disconnect BOSH client on shutdown
</li>
<li>[<a href='https://issues.igniterealtime.org/browse/SMACK-838'>SMACK-838</a>] - FormField.getFirstValue() throws IndexOutOfBoundsException if there are no values
</li>
</ul>
<h2>4.3.0 -- <span style="font-weight: normal;">2018-08-02</span></h2> <h2>4.3.0 -- <span style="font-weight: normal;">2018-08-02</span></h2>
<h2> Bug <h2> Bug

View File

@ -254,6 +254,16 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
*/ */
@Override @Override
protected void shutdown() { protected void shutdown() {
if (client != null) {
try {
client.disconnect();
} catch (Exception e) {
LOGGER.log(Level.WARNING, "shutdown", e);
}
client = null;
}
setWasAuthenticated(); setWasAuthenticated();
sessionID = null; sessionID = null;
done = true; done = true;

View File

@ -35,7 +35,11 @@ public class XmlUtil {
private static final TransformerFactory transformerFactory = TransformerFactory.newInstance(); private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();
static { static {
transformerFactory.setAttribute("indent-number", 2); try {
transformerFactory.setAttribute("indent-number", 2);
} catch (IllegalArgumentException e) {
LOGGER.log(Level.INFO, "XML TransformerFactory does not support indent-number attribute", e);
}
} }
public static String prettyFormatXml(CharSequence xml) { public static String prettyFormatXml(CharSequence xml) {

View File

@ -116,7 +116,7 @@ import org.jxmpp.jid.Jid;
* MamQueryArgs mamQueryArgs = MamQueryArgs.builder() * MamQueryArgs mamQueryArgs = MamQueryArgs.builder()
* .withJid(jid) * .withJid(jid)
* .setResultPageSize(10) * .setResultPageSize(10)
* .queryRecentPage() * .queryLastPage()
* .build(); * .build();
* MamQuery mamQuery = mamManager.queryArchive(mamQueryArgs); * MamQuery mamQuery = mamManager.queryArchive(mamQueryArgs);
* } * }
@ -435,6 +435,14 @@ public final class MamManager extends Manager {
return this; return this;
} }
/**
* Query from the last, i.e. most recent, page of the archive. This will return the very last page of the
* archive holding the most recent matching messages. You usually would page backwards from there on.
*
* @return a reference to this builder.
* @see <a href="https://xmpp.org/extensions/xep-0059.html#last">XEP-0059 § 2.5. Requesting the Last Page in
* a Result Set</a>
*/
public Builder queryLastPage() { public Builder queryLastPage() {
return beforeUid(""); return beforeUid("");
} }

View File

@ -204,7 +204,10 @@ public class MultiUserChat {
@Override @Override
public void processStanza(final Stanza packet) { public void processStanza(final Stanza packet) {
final Presence presence = (Presence) packet; final Presence presence = (Presence) packet;
final EntityFullJid from = presence.getFrom().asEntityFullJidOrThrow(); final EntityFullJid from = presence.getFrom().asEntityFullJidIfPossible();
if (from == null) {
return;
}
final EntityFullJid myRoomJID = myRoomJid; final EntityFullJid myRoomJID = myRoomJid;
final boolean isUserStatusModification = presence.getFrom().equals(myRoomJID); final boolean isUserStatusModification = presence.getFrom().equals(myRoomJID);

View File

@ -19,6 +19,7 @@ package org.jivesoftware.smackx.muc;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -392,19 +393,46 @@ public final class MultiUserChatManager extends Manager {
* @throws NotConnectedException * @throws NotConnectedException
* @throws InterruptedException * @throws InterruptedException
* @throws NotAMucServiceException * @throws NotAMucServiceException
* @deprecated use {@link #getRoomsHostedBy(DomainBareJid)} instead.
*/ */
@Deprecated
// TODO: Remove in Smack 4.4.
public List<HostedRoom> getHostedRooms(DomainBareJid serviceName) throws NoResponseException, XMPPErrorException, public List<HostedRoom> getHostedRooms(DomainBareJid serviceName) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotAMucServiceException { NotConnectedException, InterruptedException, NotAMucServiceException {
Map<EntityBareJid, HostedRoom> hostedRooms = getRoomsHostedBy(serviceName);
return new ArrayList<>(hostedRooms.values());
}
/**
* Returns a Map of HostedRooms where each HostedRoom has the XMPP address of the room and the room's name.
* Once discovered the rooms hosted by a chat service it is possible to discover more detailed room information or
* join the room.
*
* @param serviceName the service that is hosting the rooms to discover.
* @return a map from the room's address to its HostedRoom information.
* @throws XMPPErrorException
* @throws NoResponseException
* @throws NotConnectedException
* @throws InterruptedException
* @throws NotAMucServiceException
* @since 4.3.1
*/
public Map<EntityBareJid, HostedRoom> getRoomsHostedBy(DomainBareJid serviceName) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotAMucServiceException {
if (!providesMucService(serviceName)) { if (!providesMucService(serviceName)) {
throw new NotAMucServiceException(serviceName); throw new NotAMucServiceException(serviceName);
} }
ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection()); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection());
DiscoverItems discoverItems = discoManager.discoverItems(serviceName); DiscoverItems discoverItems = discoManager.discoverItems(serviceName);
List<DiscoverItems.Item> items = discoverItems.getItems(); List<DiscoverItems.Item> items = discoverItems.getItems();
List<HostedRoom> answer = new ArrayList<HostedRoom>(items.size());
Map<EntityBareJid, HostedRoom> answer = new HashMap<>(items.size());
for (DiscoverItems.Item item : items) { for (DiscoverItems.Item item : items) {
answer.add(new HostedRoom(item)); HostedRoom hostedRoom = new HostedRoom(item);
HostedRoom previousRoom = answer.put(hostedRoom.getJid(), hostedRoom);
assert previousRoom == null;
} }
return answer; return answer;
} }

View File

@ -261,12 +261,14 @@ public class FormField implements NamedElement {
*/ */
public String getFirstValue() { public String getFirstValue() {
CharSequence firstValue; CharSequence firstValue;
synchronized (values) { synchronized (values) {
if (values.isEmpty()) {
return null;
}
firstValue = values.get(0); firstValue = values.get(0);
} }
if (firstValue == null) {
return null;
}
return firstValue.toString(); return firstValue.toString();
} }

View File

@ -951,8 +951,7 @@ public final class Roster extends Manager {
// This is used in case no available presence is found // This is used in case no available presence is found
Presence unavailable = null; Presence unavailable = null;
for (Resourcepart resource : userPresences.keySet()) { for (Presence p : userPresences.values()) {
Presence p = userPresences.get(resource);
if (!p.isAvailable()) { if (!p.isAvailable()) {
unavailable = p; unavailable = p;
continue; continue;