diff --git a/src/main/java/im/conversations/android/xmpp/Managers.java b/src/main/java/im/conversations/android/xmpp/Managers.java index 6ef4e59f7..121a444d2 100644 --- a/src/main/java/im/conversations/android/xmpp/Managers.java +++ b/src/main/java/im/conversations/android/xmpp/Managers.java @@ -14,6 +14,7 @@ import im.conversations.android.xmpp.manager.NickManager; import im.conversations.android.xmpp.manager.PepManager; import im.conversations.android.xmpp.manager.PresenceManager; import im.conversations.android.xmpp.manager.PubSubManager; +import im.conversations.android.xmpp.manager.ReceiptManager; import im.conversations.android.xmpp.manager.RosterManager; public final class Managers { @@ -33,6 +34,7 @@ public final class Managers { .put(PepManager.class, new PepManager(context, connection)) .put(PresenceManager.class, new PresenceManager(context, connection)) .put(PubSubManager.class, new PubSubManager(context, connection)) + .put(ReceiptManager.class, new ReceiptManager(context, connection)) .put(RosterManager.class, new RosterManager(context, connection)) .build(); } diff --git a/src/main/java/im/conversations/android/xmpp/manager/CarbonsManager.java b/src/main/java/im/conversations/android/xmpp/manager/CarbonsManager.java index 740266289..d24a47214 100644 --- a/src/main/java/im/conversations/android/xmpp/manager/CarbonsManager.java +++ b/src/main/java/im/conversations/android/xmpp/manager/CarbonsManager.java @@ -20,7 +20,8 @@ public class CarbonsManager extends AbstractManager { public CarbonsManager(Context context, XmppConnection connection) { super(context, connection); - this.messageProcessor = new MessageProcessor(context, connection, false); + this.messageProcessor = + new MessageProcessor(context, connection, MessageProcessor.Level.CARBON); } public void enable() { diff --git a/src/main/java/im/conversations/android/xmpp/manager/ReceiptManager.java b/src/main/java/im/conversations/android/xmpp/manager/ReceiptManager.java new file mode 100644 index 000000000..78ce5845f --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/manager/ReceiptManager.java @@ -0,0 +1,43 @@ +package im.conversations.android.xmpp.manager; + +import android.content.Context; +import com.google.common.base.Strings; +import eu.siacs.conversations.xmpp.Jid; +import im.conversations.android.xmpp.XmppConnection; +import im.conversations.android.xmpp.model.DeliveryReceiptRequest; +import im.conversations.android.xmpp.model.markers.Markable; +import im.conversations.android.xmpp.model.receipts.Received; +import im.conversations.android.xmpp.model.receipts.Request; +import im.conversations.android.xmpp.model.stanza.Message; +import java.util.Collection; + +public class ReceiptManager extends AbstractManager { + + public ReceiptManager(Context context, XmppConnection connection) { + super(context, connection); + } + + public void received( + final Jid from, + final String id, + Collection deliveryReceiptRequests) { + if (deliveryReceiptRequests.isEmpty() || Strings.isNullOrEmpty(id)) { + return; + } + // TODO check roster + final Message response = new Message(); + response.setTo(from); + for (final DeliveryReceiptRequest request : deliveryReceiptRequests) { + if (request instanceof Request) { + final var received = response.addExtension(new Received()); + received.setId(id); + } else if (request instanceof Markable) { + final var received = + response.addExtension( + new im.conversations.android.xmpp.model.markers.Received()); + received.setId(id); + } + } + connection.sendMessagePacket(response); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/DeliveryReceiptRequest.java b/src/main/java/im/conversations/android/xmpp/model/DeliveryReceiptRequest.java new file mode 100644 index 000000000..a5a7533bb --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/DeliveryReceiptRequest.java @@ -0,0 +1,8 @@ +package im.conversations.android.xmpp.model; + +public abstract class DeliveryReceiptRequest extends Extension { + + protected DeliveryReceiptRequest(Class clazz) { + super(clazz); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/markers/Markable.java b/src/main/java/im/conversations/android/xmpp/model/markers/Markable.java new file mode 100644 index 000000000..08161af70 --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/markers/Markable.java @@ -0,0 +1,12 @@ +package im.conversations.android.xmpp.model.markers; + +import im.conversations.android.annotation.XmlElement; +import im.conversations.android.xmpp.model.DeliveryReceiptRequest; + +@XmlElement +public class Markable extends DeliveryReceiptRequest { + + public Markable() { + super(Markable.class); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/markers/Received.java b/src/main/java/im/conversations/android/xmpp/model/markers/Received.java new file mode 100644 index 000000000..bb350be4d --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/markers/Received.java @@ -0,0 +1,16 @@ +package im.conversations.android.xmpp.model.markers; + +import im.conversations.android.annotation.XmlElement; +import im.conversations.android.xmpp.model.Extension; + +@XmlElement +public class Received extends Extension { + + public Received() { + super(Received.class); + } + + public void setId(String id) { + this.setAttribute("id", id); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/markers/package-info.java b/src/main/java/im/conversations/android/xmpp/model/markers/package-info.java new file mode 100644 index 000000000..ff62e26b7 --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/markers/package-info.java @@ -0,0 +1,5 @@ +@XmlPackage(namespace = Namespace.CHAT_MARKERS) +package im.conversations.android.xmpp.model.markers; + +import eu.siacs.conversations.xml.Namespace; +import im.conversations.android.annotation.XmlPackage; 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 new file mode 100644 index 000000000..07d904bc8 --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/receipts/Received.java @@ -0,0 +1,16 @@ +package im.conversations.android.xmpp.model.receipts; + +import im.conversations.android.annotation.XmlElement; +import im.conversations.android.xmpp.model.Extension; + +@XmlElement +public class Received extends Extension { + + public Received() { + super(Received.class); + } + + public void setId(String id) { + this.setAttribute("id", id); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/receipts/Request.java b/src/main/java/im/conversations/android/xmpp/model/receipts/Request.java new file mode 100644 index 000000000..684477af3 --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/receipts/Request.java @@ -0,0 +1,12 @@ +package im.conversations.android.xmpp.model.receipts; + +import im.conversations.android.annotation.XmlElement; +import im.conversations.android.xmpp.model.DeliveryReceiptRequest; + +@XmlElement +public class Request extends DeliveryReceiptRequest { + + public Request() { + super(Request.class); + } +} diff --git a/src/main/java/im/conversations/android/xmpp/model/receipts/package-info.java b/src/main/java/im/conversations/android/xmpp/model/receipts/package-info.java new file mode 100644 index 000000000..196a915fd --- /dev/null +++ b/src/main/java/im/conversations/android/xmpp/model/receipts/package-info.java @@ -0,0 +1,5 @@ +@XmlPackage(namespace = Namespace.DELIVERY_RECEIPTS) +package im.conversations.android.xmpp.model.receipts; + +import eu.siacs.conversations.xml.Namespace; +import im.conversations.android.annotation.XmlPackage; diff --git a/src/main/java/im/conversations/android/xmpp/processor/MessageProcessor.java b/src/main/java/im/conversations/android/xmpp/processor/MessageProcessor.java index 0d86adbb9..85de45bc6 100644 --- a/src/main/java/im/conversations/android/xmpp/processor/MessageProcessor.java +++ b/src/main/java/im/conversations/android/xmpp/processor/MessageProcessor.java @@ -1,10 +1,12 @@ package im.conversations.android.xmpp.processor; import android.content.Context; -import com.google.common.base.Strings; +import eu.siacs.conversations.xmpp.Jid; import im.conversations.android.xmpp.XmppConnection; import im.conversations.android.xmpp.manager.CarbonsManager; import im.conversations.android.xmpp.manager.PubSubManager; +import im.conversations.android.xmpp.manager.ReceiptManager; +import im.conversations.android.xmpp.model.DeliveryReceiptRequest; import im.conversations.android.xmpp.model.carbons.Received; import im.conversations.android.xmpp.model.carbons.Sent; import im.conversations.android.xmpp.model.pubsub.event.Event; @@ -17,50 +19,66 @@ public class MessageProcessor extends XmppConnection.Delegate implements Consume private static final Logger LOGGER = LoggerFactory.getLogger(MessageProcessor.class); - private final boolean isRoot; + private final Level level; public MessageProcessor(final Context context, final XmppConnection connection) { - this(context, connection, true); + this(context, connection, Level.ROOT); } public MessageProcessor( - final Context context, final XmppConnection connection, final boolean isRoot) { + final Context context, final XmppConnection connection, final Level level) { super(context, connection); - this.isRoot = isRoot; + this.level = level; } @Override public void accept(final Message message) { - if (isRoot && connection.fromServer(message) && message.hasExtension(Received.class)) { + if (isRoot() && connection.fromServer(message) && message.hasExtension(Received.class)) { getManager(CarbonsManager.class).handleReceived(message.getExtension(Received.class)); return; } - if (isRoot && connection.fromServer(message) && message.hasExtension(Sent.class)) { + if (isRoot() && connection.fromServer(message) && message.hasExtension(Sent.class)) { getManager(CarbonsManager.class).handleSent(message.getExtension(Sent.class)); return; } - if (isRoot && message.hasExtension(Event.class)) { + if (isRoot() && message.hasExtension(Event.class)) { getManager(PubSubManager.class).handleEvent(message); return; } - final String body = message.getBody(); - if (!Strings.isNullOrEmpty(body)) { - LOGGER.info("'{}' from {}", body, message.getFrom()); - } + final String id = message.getId(); + final Jid from = message.getFrom(); LOGGER.info("Message received {}", message.getExtensionIds()); - // TODO process receipt requests (184 + 333) + // TODO only do this if transformation was successful or nothing to transform + if (isRealtimeProcessor()) { + final var requests = message.getExtensions(DeliveryReceiptRequest.class); + getManager(ReceiptManager.class).received(from, id, requests); + } + + // TODO parse chat states // TODO collect Extensions that require transformation (everything that will end up in the // message tables) - // TODO pass pubsub events to pubsub manager - // TODO pass JMI to JingleManager } + + private boolean isRoot() { + return this.level == Level.ROOT; + } + + private boolean isRealtimeProcessor() { + return this.level != Level.ARCHIVE; + } + + public enum Level { + ROOT, + CARBON, + ARCHIVE + } }