MessageArchiveService.java

  1package eu.siacs.conversations.services;
  2
  3import android.util.Log;
  4
  5import java.math.BigInteger;
  6import java.util.HashSet;
  7
  8import eu.siacs.conversations.Config;
  9import eu.siacs.conversations.entities.Account;
 10import eu.siacs.conversations.entities.Conversation;
 11import eu.siacs.conversations.xml.Element;
 12import eu.siacs.conversations.xmpp.OnIqPacketReceived;
 13import eu.siacs.conversations.xmpp.jid.Jid;
 14import eu.siacs.conversations.xmpp.stanzas.IqPacket;
 15
 16public class MessageArchiveService {
 17
 18	private final XmppConnectionService mXmppConnectionService;
 19
 20	private final HashSet<Query> queries = new HashSet<Query>();
 21
 22	public MessageArchiveService(final XmppConnectionService service) {
 23		this.mXmppConnectionService = service;
 24	}
 25
 26	public void query(final Conversation conversation) {
 27		synchronized (this.queries) {
 28			final Account account = conversation.getAccount();
 29			long start = conversation.getLastMessageReceived();
 30			long end = account.getXmppConnection().getLastSessionEstablished();
 31			final Query query = new Query(conversation, start, end);
 32			this.queries.add(query);
 33			IqPacket packet = this.mXmppConnectionService.getIqGenerator().queryMessageArchiveManagement(query);
 34			this.mXmppConnectionService.sendIqPacket(account, packet, new OnIqPacketReceived() {
 35				@Override
 36				public void onIqPacketReceived(Account account, IqPacket packet) {
 37					Log.d(Config.LOGTAG, packet.toString());
 38				}
 39			});
 40		}
 41	}
 42
 43	public void processFin(Element fin) {
 44		if (fin == null) {
 45			return;
 46		}
 47		Query query = findQuery(fin.getAttribute("queryid"));
 48		if (query == null) {
 49			return;
 50		}
 51		Log.d(Config.LOGTAG,"fin "+fin.toString());
 52		boolean complete = fin.getAttributeAsBoolean("complete");
 53		Element set = fin.findChild("set","http://jabber.org/protocol/rsm");
 54		Element last = set == null ? null : set.findChild("last");
 55		if (complete || last == null) {
 56			Log.d(Config.LOGTAG,"completed mam query for "+query.getWith().toString());
 57			synchronized (this.queries) {
 58				this.queries.remove(query);
 59			}
 60		} else {
 61			Query nextQuery = query.next(last == null ? null : last.getContent());
 62			IqPacket packet = this.mXmppConnectionService.getIqGenerator().queryMessageArchiveManagement(nextQuery);
 63			synchronized (this.queries) {
 64				this.queries.remove(query);
 65				this.queries.add(nextQuery);
 66			}
 67			Log.d(Config.LOGTAG,packet.toString());
 68			this.mXmppConnectionService.sendIqPacket(query.getConversation().getAccount(),packet,new OnIqPacketReceived() {
 69				@Override
 70				public void onIqPacketReceived(Account account, IqPacket packet) {
 71					Log.d(Config.LOGTAG,packet.toString());
 72				}
 73			});
 74		}
 75	}
 76
 77	private Query findQuery(String id) {
 78		if (id == null) {
 79			return null;
 80		}
 81		synchronized (this.queries) {
 82			for(Query query : this.queries) {
 83				if (query.getQueryId().equals(id)) {
 84					return query;
 85				}
 86			}
 87			return null;
 88		}
 89	}
 90
 91	public class Query {
 92		private long start;
 93		private long end;
 94		private Jid with;
 95		private String queryId;
 96		private String after = null;
 97		private Conversation conversation;
 98
 99		public Query(Conversation conversation, long start, long end) {
100			this.conversation = conversation;
101			this.with = conversation.getContactJid().toBareJid();
102			this.start = start;
103			this.end = end;
104			this.queryId = new BigInteger(50, mXmppConnectionService.getRNG()).toString(32);
105		}
106
107		public Query next(String after) {
108			Query query = new Query(this.conversation,this.start,this.end);
109			query.after = after;
110			return query;
111		}
112
113		public String getAfter() {
114			return after;
115		}
116
117		public String getQueryId() {
118			return queryId;
119		}
120
121		public Jid getWith() {
122			return with;
123		}
124
125		public long getStart() {
126			return start;
127		}
128
129		public long getEnd() {
130			return end;
131		}
132
133		public Conversation getConversation() {
134			return conversation;
135		}
136	}
137}