package org.mercury_im.messenger.core.store.message; import org.jivesoftware.smack.chat2.IncomingChatMessageListener; import org.jivesoftware.smack.chat2.OutgoingChatMessageListener; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smackx.delay.packet.DelayInformation; import org.jxmpp.jid.EntityBareJid; import org.mercury_im.messenger.core.SchedulersFacade; import org.mercury_im.messenger.core.data.repository.DirectChatRepository; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.data.repository.PeerRepository; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.message.Message; import org.mercury_im.messenger.entity.message.MessageDirection; import java.util.Date; import java.util.logging.Level; import java.util.logging.Logger; import javax.inject.Inject; import javax.inject.Singleton; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; @Singleton public class MercuryMessageStore implements IncomingChatMessageListener, OutgoingChatMessageListener { private static final Logger LOGGER = Logger.getLogger(MercuryMessageStore.class.getName()); private final MessageRepository messageRepository; private final DirectChatRepository directChatRepository; private final PeerRepository peerRepository; private final SchedulersFacade schedulers; private Account account; private CompositeDisposable disposable = new CompositeDisposable(); @Inject public MercuryMessageStore(Account account, PeerRepository peerRepository, DirectChatRepository directChatRepository, MessageRepository messageRepository, SchedulersFacade schedulers) { this.account = account; this.peerRepository = peerRepository; this.directChatRepository = directChatRepository; this.messageRepository = messageRepository; this.schedulers = schedulers; } @Override public void newIncomingMessage(EntityBareJid from, org.jivesoftware.smack.packet.Message smackMessage, org.jivesoftware.smack.chat2.Chat smackChat) { Message message = new Message(); message.setDirection(MessageDirection.incoming); DelayInformation delayInformation = DelayInformation.from(smackMessage); message.setTimestamp(delayInformation != null ? delayInformation.getStamp() : new Date()); message.setSender(from.asEntityBareJidString()); message.setRecipient(smackMessage.getTo().asBareJid().toString()); if (smackMessage.getBody() != null) { message.setBody(smackMessage.getBody()); } disposable.add(writeMessageToStore(from.asEntityBareJidString(), message)); } @Override public void newOutgoingMessage(EntityBareJid to, MessageBuilder smackMessage, org.jivesoftware.smack.chat2.Chat smackChat) { Message message = new Message(); message.setDirection(MessageDirection.outgoing); message.setTimestamp(new Date()); message.setSender(account.getAddress()); message.setRecipient(to.asBareJid().toString()); if (smackMessage.getBody() != null) { message.setBody(smackMessage.getBody().getMessage()); } disposable.add(writeMessageToStore(to.asEntityBareJidString(), message)); } private Disposable writeMessageToStore(String peer, Message message) { return peerRepository.getOrCreatePeer(account, peer) .flatMap(directChatRepository::getOrCreateChatWithPeer) .flatMap(chat -> messageRepository.insertMessage(chat, message)) .subscribeOn(schedulers.getIoScheduler()) .subscribe(m -> LOGGER.log(Level.INFO, "Message written"), e -> LOGGER.log(Level.SEVERE, "Error: ", e)); } }