diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 6ff2337cc2bc3175877ee032f0e3b0e55f138b18..d8f71a0b4f1836f6bdbfe5fbd3385e43d99fe366 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -17,11 +17,12 @@ import eu.siacs.conversations.xmpp.jingle.JingleRtpConnection; import eu.siacs.conversations.xmpp.jingle.Media; import eu.siacs.conversations.xmpp.jingle.stanzas.Reason; import im.conversations.android.xmpp.model.correction.Replace; +import im.conversations.android.xmpp.model.hints.Store; import im.conversations.android.xmpp.model.reactions.Reaction; import im.conversations.android.xmpp.model.reactions.Reactions; +import im.conversations.android.xmpp.model.receipts.Received; import im.conversations.android.xmpp.model.unique.OriginId; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.Locale; @@ -258,19 +259,14 @@ public class MessageGenerator extends AbstractGenerator { } public im.conversations.android.xmpp.model.stanza.Message received( - Account account, final Jid from, final String id, - ArrayList namespaces, - im.conversations.android.xmpp.model.stanza.Message.Type type) { + final im.conversations.android.xmpp.model.stanza.Message.Type type) { final var receivedPacket = new im.conversations.android.xmpp.model.stanza.Message(); receivedPacket.setType(type); receivedPacket.setTo(from); - receivedPacket.setFrom(account.getJid()); - for (final String namespace : namespaces) { - receivedPacket.addChild("received", namespace).setAttribute("id", id); - } - receivedPacket.addChild("store", "urn:xmpp:hints"); + receivedPacket.addExtension(new Received(id)); + receivedPacket.addExtension(new Store()); return receivedPacket; } diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java index 3907222c66b778d22092fc50de9b16350f462261..b6194ccd1be5f90ac229a85b32e3143fa8356aba 100644 --- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java +++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java @@ -45,9 +45,11 @@ import im.conversations.android.xmpp.model.forward.Forwarded; import im.conversations.android.xmpp.model.markers.Displayed; import im.conversations.android.xmpp.model.occupant.OccupantId; import im.conversations.android.xmpp.model.oob.OutOfBandData; +import im.conversations.android.xmpp.model.pubsub.event.Event; import im.conversations.android.xmpp.model.reactions.Reactions; +import im.conversations.android.xmpp.model.receipts.Request; +import im.conversations.android.xmpp.model.unique.StanzaId; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Date; @@ -72,7 +74,9 @@ public class MessageParser extends AbstractParser } private static String extractStanzaId( - Element packet, boolean isTypeGroupChat, Conversation conversation) { + final im.conversations.android.xmpp.model.stanza.Message packet, + final boolean isTypeGroupChat, + final Conversation conversation) { final Jid by; final boolean safeToExtract; if (isTypeGroupChat) { @@ -83,23 +87,14 @@ public class MessageParser extends AbstractParser by = account.getJid().asBareJid(); safeToExtract = account.getXmppConnection().getFeatures().stanzaIds(); } - return safeToExtract ? extractStanzaId(packet, by) : null; + return safeToExtract ? StanzaId.get(packet, by) : null; } - private static String extractStanzaId(Account account, Element packet) { + private static String extractStanzaId( + final Account account, + final im.conversations.android.xmpp.model.stanza.Message packet) { final boolean safeToExtract = account.getXmppConnection().getFeatures().stanzaIds(); - return safeToExtract ? extractStanzaId(packet, account.getJid().asBareJid()) : null; - } - - private static String extractStanzaId(Element packet, Jid by) { - for (Element child : packet.getChildren()) { - if (child.getName().equals("stanza-id") - && Namespace.STANZA_IDS.equals(child.getNamespace()) - && by.equals(Jid.Invalid.getNullForInvalid(child.getAttributeAsJid("by")))) { - return child.getAttribute("id"); - } - } - return null; + return safeToExtract ? StanzaId.get(packet, account.getJid().asBareJid()) : null; } private static Jid getTrueCounterpart(Element mucUserElement, Jid fallback) { @@ -249,7 +244,7 @@ public class MessageParser extends AbstractParser return null; } - private void parseEvent(final Element event, final Jid from, final Account account) { + private void parseEvent(final Event event, final Jid from, final Account account) { final Element items = event.findChild("items"); final String node = items == null ? null : items.getAttribute("node"); if ("urn:xmpp:avatar:metadata".equals(node)) { @@ -551,7 +546,6 @@ public class MessageParser extends AbstractParser final var encrypted = packet.getOnlyExtension(im.conversations.android.xmpp.model.pgp.Encrypted.class); final String pgpEncrypted = encrypted == null ? null : encrypted.getContent(); - ; final var oob = packet.getExtension(OutOfBandData.class); final String oobUrl = oob != null ? oob.getURL() : null; @@ -592,7 +586,8 @@ public class MessageParser extends AbstractParser final Jid mucTrueCounterPartByPresence; if (conversation != null) { final var mucOptions = conversation.getMucOptions(); - occupant = mucOptions.occupantId() ? packet.getExtension(OccupantId.class) : null; + occupant = + mucOptions.occupantId() ? packet.getOnlyExtension(OccupantId.class) : null; final var user = occupant == null ? null : mucOptions.findUserByOccupantId(occupant.getId()); mucTrueCounterPartByPresence = user == null ? null : user.getRealJid(); @@ -611,7 +606,8 @@ public class MessageParser extends AbstractParser mXmppConnectionService.find(account, from.asBareJid()); if (conversation != null) { final var mucOptions = conversation.getMucOptions(); - occupant = mucOptions.occupantId() ? packet.getExtension(OccupantId.class) : null; + occupant = + mucOptions.occupantId() ? packet.getOnlyExtension(OccupantId.class) : null; } else { occupant = null; } @@ -1396,8 +1392,7 @@ public class MessageParser extends AbstractParser // end no body } - final Element event = - original.findChild("event", "http://jabber.org/protocol/pubsub#event"); + final var event = original.getExtension(Event.class); if (event != null && Jid.Invalid.hasValidFrom(original) && original.getFrom().isBareJid()) { if (event.hasChild("items")) { parseEvent(event, original.getFrom(), account); @@ -1696,27 +1691,14 @@ public class MessageParser extends AbstractParser final Account account, final im.conversations.android.xmpp.model.stanza.Message packet, final String remoteMsgId, - MessageArchiveService.Query query) { - final boolean markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0"); - final boolean request = packet.hasChild("request", "urn:xmpp:receipts"); + final MessageArchiveService.Query query) { + final var request = packet.hasExtension(Request.class); if (query == null) { - final ArrayList receiptsNamespaces = new ArrayList<>(); - if (markable) { - receiptsNamespaces.add("urn:xmpp:chat-markers:0"); - } if (request) { - receiptsNamespaces.add("urn:xmpp:receipts"); - } - if (receiptsNamespaces.size() > 0) { final var receipt = mXmppConnectionService .getMessageGenerator() - .received( - account, - packet.getFrom(), - remoteMsgId, - receiptsNamespaces, - packet.getType()); + .received(packet.getFrom(), remoteMsgId, packet.getType()); mXmppConnectionService.sendMessagePacket(account, receipt); } } else if (query.isCatchup()) { diff --git a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java index 038537dfe28d8051b0fd5aa8021553b06178180a..244da8e40807e568c07f9427c16e4e8a2708dd91 100644 --- a/src/main/java/eu/siacs/conversations/parser/PresenceParser.java +++ b/src/main/java/eu/siacs/conversations/parser/PresenceParser.java @@ -77,7 +77,7 @@ public class PresenceParser extends AbstractParser if (item != null && !from.isBareJid()) { mucOptions.setError(MucOptions.Error.NONE); final MucOptions.User user = parseItem(conversation, item, from); - final var occupant = packet.getExtension(OccupantId.class); + final var occupant = packet.getOnlyExtension(OccupantId.class); final String occupantId = mucOptions.occupantId() && occupant != null ? occupant.getId() diff --git a/src/main/java/im/conversations/android/xmpp/model/receipts/Received.java b/src/main/java/im/conversations/android/xmpp/model/receipts/Received.java index 71fe922c158adeb678b30e6181047329e5dc0784..c3c987a5c4c3f4bbcde5868397a676640d60a968 100644 --- a/src/main/java/im/conversations/android/xmpp/model/receipts/Received.java +++ b/src/main/java/im/conversations/android/xmpp/model/receipts/Received.java @@ -10,6 +10,11 @@ public class Received extends DeliveryReceipt { super(Received.class); } + public Received(final String id) { + super(Received.class); + this.setId(id); + } + public void setId(String id) { this.setAttribute("id", id); } diff --git a/src/main/java/im/conversations/android/xmpp/model/unique/StanzaId.java b/src/main/java/im/conversations/android/xmpp/model/unique/StanzaId.java index 23b0fdcac823de630719bf14f8c47a559a2fbcfd..0078bcbae2be3558658908c98a48e71d6636ac42 100644 --- a/src/main/java/im/conversations/android/xmpp/model/unique/StanzaId.java +++ b/src/main/java/im/conversations/android/xmpp/model/unique/StanzaId.java @@ -1,8 +1,10 @@ package im.conversations.android.xmpp.model.unique; +import com.google.common.collect.ImmutableMap; import eu.siacs.conversations.xmpp.Jid; import im.conversations.android.annotation.XmlElement; import im.conversations.android.xmpp.model.Extension; +import java.util.Map; @XmlElement public class StanzaId extends Extension { @@ -18,4 +20,23 @@ public class StanzaId extends Extension { public String getId() { return this.getAttribute("id"); } + + public static String get( + final im.conversations.android.xmpp.model.stanza.Message packet, final Jid by) { + final var builder = new ImmutableMap.Builder(); + for (final var stanzaId : packet.getExtensions(StanzaId.class)) { + final var id = stanzaId.getId(); + final var byAttribute = Jid.Invalid.getNullForInvalid(stanzaId.getBy()); + if (byAttribute != null && id != null) { + builder.put(byAttribute, id); + } + } + final Map byToId; + try { + byToId = builder.buildOrThrow(); + } catch (final IllegalArgumentException e) { + return null; + } + return byToId.get(by); + } }