From 476ab656ef0a50b081d92750b8b4251652ef4624 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Fri, 6 Jun 2014 18:26:40 +0200 Subject: [PATCH] refactored presence parsing into dedicated class --- .../conversations/parser/AbstractParser.java | 53 +++++++++ .../conversations/parser/MessageParser.java | 48 +++----- .../conversations/parser/PresenceParser.java | 103 ++++++++++++++++ .../services/XmppConnectionService.java | 112 ++---------------- 4 files changed, 178 insertions(+), 138 deletions(-) create mode 100644 src/eu/siacs/conversations/parser/AbstractParser.java create mode 100644 src/eu/siacs/conversations/parser/PresenceParser.java diff --git a/src/eu/siacs/conversations/parser/AbstractParser.java b/src/eu/siacs/conversations/parser/AbstractParser.java new file mode 100644 index 000000000..8c6ad2ab2 --- /dev/null +++ b/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; + } + } + } +} diff --git a/src/eu/siacs/conversations/parser/MessageParser.java b/src/eu/siacs/conversations/parser/MessageParser.java index ab75d6767..12e2aa16c 100644 --- a/src/eu/siacs/conversations/parser/MessageParser.java +++ b/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 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(); - } - } } diff --git a/src/eu/siacs/conversations/parser/PresenceParser.java b/src/eu/siacs/conversations/parser/PresenceParser.java new file mode 100644 index 000000000..25a234238 --- /dev/null +++ b/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); + } + } + } + } + +} diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index 223b14438..6b9ffcf7d 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/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 accounts; private List 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)) {