refactored presence parsing into dedicated class

Daniel Gultsch created

Change summary

src/eu/siacs/conversations/parser/AbstractParser.java          |  53 +
src/eu/siacs/conversations/parser/MessageParser.java           |  48 -
src/eu/siacs/conversations/parser/PresenceParser.java          | 103 +++
src/eu/siacs/conversations/services/XmppConnectionService.java | 112 ---
4 files changed, 178 insertions(+), 138 deletions(-)

Detailed changes

src/eu/siacs/conversations/parser/AbstractParser.java 🔗

@@ -0,0 +1,53 @@
+package eu.siacs.conversations.parser;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.xml.Element;
+
+public abstract class AbstractParser {
+	
+	protected XmppConnectionService mXmppConnectionService;
+
+	protected AbstractParser(XmppConnectionService service) {
+		this.mXmppConnectionService = service;
+	}
+	
+	protected long getTimestamp(Element packet) {
+		if (packet.hasChild("delay")) {
+			try {
+				String stamp = packet.findChild("delay").getAttribute(
+						"stamp");
+				stamp = stamp.replace("Z", "+0000");
+				Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
+						.parse(stamp);
+				return date.getTime();
+			} catch (ParseException e) {
+				return System.currentTimeMillis();
+			}
+		} else {
+			return System.currentTimeMillis();
+		}
+	}
+	
+	protected void updateLastseen(Element packet, Account account) {
+		String[] fromParts = packet.getAttribute("from").split("/");
+		String from = fromParts[0];
+		String presence = null;
+		if (fromParts.length >= 2) {
+			presence = fromParts[1];
+		}
+		Contact contact = account.getRoster().getContact(from);
+		long timestamp = getTimestamp(packet);
+		if (timestamp >= contact.lastseen.time) {
+			contact.lastseen.time = timestamp;
+			if (presence!=null) {
+				contact.lastseen.presence = presence;
+			}
+		}
+	}
+}

src/eu/siacs/conversations/parser/MessageParser.java 🔗

@@ -13,13 +13,10 @@ import eu.siacs.conversations.services.XmppConnectionService;
 import eu.siacs.conversations.xml.Element;
 import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
 
-public class MessageParser {
-
-	protected static final String LOGTAG = "xmppService";
-	private XmppConnectionService mXmppConnectionService;
+public class MessageParser extends AbstractParser {
 
 	public MessageParser(XmppConnectionService service) {
-		this.mXmppConnectionService = service;
+		super(service);
 	}
 
 	public Message parseChat(MessagePacket packet, Account account) {
@@ -83,7 +80,6 @@ public class MessageParser {
 			body = otrSession.transformReceiving(body);
 			SessionStatus after = otrSession.getSessionStatus();
 			if ((before != after) && (after == SessionStatus.ENCRYPTED)) {
-				Log.d(LOGTAG, "otr session etablished");
 				List<Message> messages = conversation.getMessages();
 				for (int i = 0; i < messages.size(); ++i) {
 					Message msg = messages.get(i);
@@ -101,7 +97,6 @@ public class MessageParser {
 				mXmppConnectionService.updateUi(conversation, false);
 			} else if ((before != after) && (after == SessionStatus.FINISHED)) {
 				conversation.resetOtrSession();
-				Log.d(LOGTAG, "otr session stoped");
 			}
 			// isEmpty is a work around for some weird clients which send emtpty
 			// strings over otr
@@ -109,8 +104,10 @@ public class MessageParser {
 				return null;
 			}
 			conversation.setLatestMarkableMessageId(getMarkableMessageId(packet));
-			return new Message(conversation, packet.getFrom(), body,
+			Message finishedMessage = new Message(conversation, packet.getFrom(), body,
 					Message.ENCRYPTION_OTR, Message.STATUS_RECIEVED);
+			finishedMessage.setTime(getTimestamp(packet));
+			return finishedMessage;
 		} catch (Exception e) {
 			conversation.resetOtrSession();
 			return null;
@@ -144,13 +141,16 @@ public class MessageParser {
 		}
 		String pgpBody = getPgpBody(packet);
 		conversation.setLatestMarkableMessageId(getMarkableMessageId(packet));
+		Message finishedMessage;
 		if (pgpBody == null) {
-			return new Message(conversation, counterPart, packet.getBody(),
+			finishedMessage = new Message(conversation, counterPart, packet.getBody(),
 					Message.ENCRYPTION_NONE, status);
 		} else {
-			return new Message(conversation, counterPart, pgpBody,
+			finishedMessage=  new Message(conversation, counterPart, pgpBody,
 					Message.ENCRYPTION_PGP, status);
 		}
+		finishedMessage.setTime(getTimestamp(packet));
+		return finishedMessage;
 	}
 
 	public Message parseCarbonMessage(MessagePacket packet, Account account) {
@@ -183,14 +183,15 @@ public class MessageParser {
 				.findOrCreateConversation(account, parts[0], false);
 		conversation.setLatestMarkableMessageId(getMarkableMessageId(packet));
 		String pgpBody = getPgpBody(message);
+		Message finishedMessage;
 		if (pgpBody != null) {
-			return new Message(conversation, fullJid, pgpBody,
-					Message.ENCRYPTION_PGP, status);
+			finishedMessage = new Message(conversation, fullJid, pgpBody,Message.ENCRYPTION_PGP, status);
 		} else {
 			String body = message.findChild("body").getContent();
-			return new Message(conversation, fullJid, body,
-					Message.ENCRYPTION_NONE, status);
+			finishedMessage=  new Message(conversation, fullJid, body,Message.ENCRYPTION_NONE, status);
 		}
+		finishedMessage.setTime(getTimestamp(message));
+		return finishedMessage;
 	}
 
 	public void parseError(MessagePacket packet, Account account) {
@@ -215,23 +216,4 @@ public class MessageParser {
 			return null;
 		}
 	}
-	
-	private void updateLastseen(Element message, Account account) {
-		String[] fromParts = message.getAttribute("from").split("/");
-		String from = fromParts[0];
-		String presence = null;
-		if (fromParts.length >= 2) {
-			presence = fromParts[1];
-		}
-		Contact contact = account.getRoster().getContact(from);
-		if (presence!=null) {
-			contact.lastseen.presence = presence;
-			contact.lastseen.time = System.currentTimeMillis();
-		} else if ((contact.getPresences().size() == 1)&&(contact.getPresences().containsKey(contact.lastseen.presence))) {
-			contact.lastseen.time = System.currentTimeMillis();
-		} else {
-			contact.lastseen.presence = null;
-			contact.lastseen.time = System.currentTimeMillis();
-		}
-	}
 }

src/eu/siacs/conversations/parser/PresenceParser.java 🔗

@@ -0,0 +1,103 @@
+package eu.siacs.conversations.parser;
+
+import android.util.Log;
+import eu.siacs.conversations.crypto.PgpEngine;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Contact;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Presences;
+import eu.siacs.conversations.services.XmppConnectionService;
+import eu.siacs.conversations.xml.Element;
+import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
+
+public class PresenceParser extends AbstractParser {
+
+	public PresenceParser(XmppConnectionService service) {
+		super(service);
+	}
+
+	public void parseConferencePresence(PresencePacket packet, Account account) {
+		PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
+		if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
+			Conversation muc = mXmppConnectionService.findMuc(packet
+					.getAttribute("from").split("/")[0], account);
+			if (muc != null) {
+				muc.getMucOptions().processPacket(packet, mPgpEngine);
+			}
+		} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
+			Conversation muc = mXmppConnectionService.findMuc(packet
+					.getAttribute("from").split("/")[0], account);
+			if (muc != null) {
+				int error = muc.getMucOptions().getError();
+				muc.getMucOptions().processPacket(packet, mPgpEngine);
+				if (muc.getMucOptions().getError() != error) {
+					mXmppConnectionService.updateUi(muc, false);
+				}
+			}
+		}
+	}
+
+	public void parseContactPresence(PresencePacket packet, Account account) {
+		String[] fromParts = packet.getAttribute("from").split("/");
+		String type = packet.getAttribute("type");
+		if (fromParts[0].equals(account.getJid())) {
+			if (fromParts.length == 2) {
+				if (type == null) {
+					account.updatePresence(fromParts[1],
+							Presences.parseShow(packet.findChild("show")));
+				} else if (type.equals("unavailable")) {
+					account.removePresence(fromParts[1]);
+				}
+			}
+
+		} else {
+			Contact contact = account.getRoster().getContact(packet.getFrom());
+			if (type == null) {
+				if (fromParts.length == 2) {
+					contact.updatePresence(fromParts[1],
+							Presences.parseShow(packet.findChild("show")));
+					PgpEngine pgp = mXmppConnectionService.getPgpEngine();
+					if (pgp != null) {
+						Element x = packet.findChild("x", "jabber:x:signed");
+						if (x != null) {
+							Element status = packet.findChild("status");
+							String msg;
+							if (status != null) {
+								msg = status.getContent();
+							} else {
+								msg = "";
+							}
+							contact.setPgpKeyId(pgp.fetchKeyId(account, msg,
+									x.getContent()));
+						}
+					}
+					mXmppConnectionService.onContactStatusChanged
+							.onContactStatusChanged(contact);
+					updateLastseen(packet, account);
+				}
+			} else if (type.equals("unavailable")) {
+				if (fromParts.length != 2) {
+					contact.clearPresences();
+				} else {
+					contact.removePresence(fromParts[1]);
+				}
+				mXmppConnectionService.onContactStatusChanged
+						.onContactStatusChanged(contact);
+			} else if (type.equals("subscribe")) {
+				if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
+					mXmppConnectionService.sendPresenceUpdatesTo(contact);
+					contact.setOption(Contact.Options.FROM);
+					contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
+					if ((contact.getOption(Contact.Options.ASKING))
+							&& (!contact.getOption(Contact.Options.TO))) {
+						mXmppConnectionService
+								.requestPresenceUpdatesFrom(contact);
+					}
+				} else {
+					contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
+				}
+			}
+		}
+	}
+
+}

src/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -1,10 +1,7 @@
 package eu.siacs.conversations.services;
 
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.Date;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Locale;
@@ -23,8 +20,8 @@ import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.Message;
 import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.entities.MucOptions.OnRenameListener;
-import eu.siacs.conversations.entities.Presences;
 import eu.siacs.conversations.parser.MessageParser;
+import eu.siacs.conversations.parser.PresenceParser;
 import eu.siacs.conversations.persistance.DatabaseBackend;
 import eu.siacs.conversations.persistance.FileBackend;
 import eu.siacs.conversations.ui.OnAccountListChangedListener;
@@ -86,6 +83,7 @@ public class XmppConnectionService extends Service {
 	private static String ACTION_MERGE_PHONE_CONTACTS = "merge_phone_contacts";
 
 	private MessageParser mMessageParser = new MessageParser(this);
+	private PresenceParser mPresenceParser = new PresenceParser(this);
 
 	private List<Account> accounts;
 	private List<Conversation> conversations = null;
@@ -96,7 +94,7 @@ public class XmppConnectionService extends Service {
 	private int convChangedListenerCount = 0;
 	private OnAccountListChangedListener accountChangedListener = null;
 	private OnTLSExceptionReceived tlsException = null;
-	private OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() {
+	public OnContactStatusChanged onContactStatusChanged = new OnContactStatusChanged() {
 
 		@Override
 		public void onContactStatusChanged(Contact contact) {
@@ -208,18 +206,6 @@ public class XmppConnectionService extends Service {
 			if ((message == null) || (message.getBody() == null)) {
 				return;
 			}
-			if (packet.hasChild("delay")) {
-				try {
-					String stamp = packet.findChild("delay").getAttribute(
-							"stamp");
-					stamp = stamp.replace("Z", "+0000");
-					Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
-							.parse(stamp);
-					message.setTime(date.getTime());
-				} catch (ParseException e) {
-					Log.d(LOGTAG, "error trying to parse date" + e.getMessage());
-				}
-			}
 			if ((confirmMessages()) && ((packet.getId() != null))) {
 				MessagePacket receivedPacket = new MessagePacket();
 				receivedPacket.setType(MessagePacket.TYPE_NORMAL);
@@ -298,95 +284,11 @@ public class XmppConnectionService extends Service {
 		public void onPresencePacketReceived(final Account account,
 				PresencePacket packet) {
 			if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
-				Conversation muc = findMuc(
-						packet.getAttribute("from").split("/")[0], account);
-				if (muc != null) {
-					muc.getMucOptions().processPacket(packet, getPgpEngine());
-				} else {
-					Log.d(LOGTAG, account.getJid()
-							+ ": could not find muc for received muc package "
-							+ packet.toString());
-				}
+				mPresenceParser.parseConferencePresence(packet, account);
 			} else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
-				Conversation muc = findMuc(
-						packet.getAttribute("from").split("/")[0], account);
-				if (muc != null) {
-					Log.d(LOGTAG,
-							account.getJid() + ": reading muc status packet "
-									+ packet.toString());
-					int error = muc.getMucOptions().getError();
-					muc.getMucOptions().processPacket(packet, getPgpEngine());
-					if ((muc.getMucOptions().getError() != error)
-							&& (convChangedListener != null)) {
-						Log.d(LOGTAG, "muc error status changed");
-						convChangedListener.onConversationListChanged();
-					}
-				}
+				mPresenceParser.parseConferencePresence(packet, account);
 			} else {
-				String[] fromParts = packet.getAttribute("from").split("/");
-				String type = packet.getAttribute("type");
-				if (fromParts[0].equals(account.getJid())) {
-					if (fromParts.length == 2) {
-						if (type == null) {
-							account.updatePresence(fromParts[1], Presences
-									.parseShow(packet.findChild("show")));
-						} else if (type.equals("unavailable")) {
-							account.removePresence(fromParts[1]);
-						}
-					}
-
-				} else {
-					Contact contact = account.getRoster().getContact(
-							packet.getFrom());
-					if (type == null) {
-						if (fromParts.length == 2) {
-							contact.updatePresence(fromParts[1], Presences
-									.parseShow(packet.findChild("show")));
-							PgpEngine pgp = getPgpEngine();
-							if (pgp != null) {
-								Element x = packet.findChild("x",
-										"jabber:x:signed");
-								if (x != null) {
-									Element status = packet.findChild("status");
-									String msg;
-									if (status != null) {
-										msg = status.getContent();
-									} else {
-										msg = "";
-									}
-									contact.setPgpKeyId(pgp.fetchKeyId(account,
-											msg, x.getContent()));
-								}
-							}
-							onContactStatusChanged
-									.onContactStatusChanged(contact);
-						}
-					} else if (type.equals("unavailable")) {
-						if (fromParts.length != 2) {
-							contact.clearPresences();
-						} else {
-							contact.removePresence(fromParts[1]);
-						}
-						onContactStatusChanged.onContactStatusChanged(contact);
-					} else if (type.equals("subscribe")) {
-						Log.d(LOGTAG, "received subscribe packet from "
-								+ packet.getFrom());
-						if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
-							Log.d(LOGTAG, "preemptive grant; granting");
-							sendPresenceUpdatesTo(contact);
-							contact.setOption(Contact.Options.FROM);
-							contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
-							if ((contact.getOption(Contact.Options.ASKING))
-									&& (!contact.getOption(Contact.Options.TO))) {
-								requestPresenceUpdatesFrom(contact);
-							}
-						} else {
-							contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
-						}
-					} else {
-						// Log.d(LOGTAG, packet.toString());
-					}
-				}
+				mPresenceParser.parseContactPresence(packet,account);
 			}
 		}
 	};
@@ -507,7 +409,7 @@ public class XmppConnectionService extends Service {
 		return message;
 	}
 
-	protected Conversation findMuc(String name, Account account) {
+	public Conversation findMuc(String name, Account account) {
 		for (Conversation conversation : this.conversations) {
 			if (conversation.getContactJid().split("/")[0].equals(name)
 					&& (conversation.getAccount() == account)) {