1package eu.siacs.conversations.parser;
2
3import eu.siacs.conversations.crypto.PgpEngine;
4import eu.siacs.conversations.entities.Account;
5import eu.siacs.conversations.entities.Contact;
6import eu.siacs.conversations.entities.Conversation;
7import eu.siacs.conversations.entities.Presences;
8import eu.siacs.conversations.services.XmppConnectionService;
9import eu.siacs.conversations.xml.Element;
10import eu.siacs.conversations.xmpp.OnPresencePacketReceived;
11import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
12
13public class PresenceParser extends AbstractParser implements
14 OnPresencePacketReceived {
15
16 public PresenceParser(XmppConnectionService service) {
17 super(service);
18 }
19
20 public void parseConferencePresence(PresencePacket packet, Account account) {
21 PgpEngine mPgpEngine = mXmppConnectionService.getPgpEngine();
22 if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
23 Conversation muc = mXmppConnectionService.findMuc(packet
24 .getAttribute("from").split("/")[0], account);
25 if (muc != null) {
26 muc.getMucOptions().processPacket(packet, mPgpEngine);
27 }
28 } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
29 Conversation muc = mXmppConnectionService.findMuc(packet
30 .getAttribute("from").split("/")[0], account);
31 if (muc != null) {
32 int error = muc.getMucOptions().getError();
33 muc.getMucOptions().processPacket(packet, mPgpEngine);
34 if (muc.getMucOptions().getError() != error) {
35 mXmppConnectionService.updateUi(muc, false);
36 }
37 }
38 }
39 }
40
41 public void parseContactPresence(PresencePacket packet, Account account) {
42 if (packet.getFrom() == null) {
43 return;
44 }
45 String[] fromParts = packet.getFrom().split("/");
46 String type = packet.getAttribute("type");
47 if (fromParts[0].equals(account.getJid())) {
48 if (fromParts.length == 2) {
49 if (type == null) {
50 account.updatePresence(fromParts[1],
51 Presences.parseShow(packet.findChild("show")));
52 } else if (type.equals("unavailable")) {
53 account.removePresence(fromParts[1]);
54 }
55 }
56
57 } else {
58 Contact contact = account.getRoster().getContact(packet.getFrom());
59 if (type == null) {
60 if (fromParts.length == 2) {
61 int sizeBefore = contact.getPresences().size();
62 contact.updatePresence(fromParts[1],
63 Presences.parseShow(packet.findChild("show")));
64 PgpEngine pgp = mXmppConnectionService.getPgpEngine();
65 if (pgp != null) {
66 Element x = packet.findChild("x", "jabber:x:signed");
67 if (x != null) {
68 Element status = packet.findChild("status");
69 String msg;
70 if (status != null) {
71 msg = status.getContent();
72 } else {
73 msg = "";
74 }
75 contact.setPgpKeyId(pgp.fetchKeyId(account, msg,
76 x.getContent()));
77 }
78 }
79 boolean online = sizeBefore < contact.getPresences().size();
80 updateLastseen(packet, account, true);
81 mXmppConnectionService.onContactStatusChanged
82 .onContactStatusChanged(contact, online);
83 }
84 } else if (type.equals("unavailable")) {
85 if (fromParts.length != 2) {
86 contact.clearPresences();
87 } else {
88 contact.removePresence(fromParts[1]);
89 }
90 mXmppConnectionService.onContactStatusChanged
91 .onContactStatusChanged(contact, false);
92 } else if (type.equals("subscribe")) {
93 if (contact.getOption(Contact.Options.PREEMPTIVE_GRANT)) {
94 mXmppConnectionService.sendPresenceUpdatesTo(contact);
95 if ((contact.getOption(Contact.Options.ASKING))
96 && (!contact.getOption(Contact.Options.TO))) {
97 mXmppConnectionService
98 .requestPresenceUpdatesFrom(contact);
99 }
100 } else {
101 contact.setOption(Contact.Options.PENDING_SUBSCRIPTION_REQUEST);
102 }
103 }
104 }
105 }
106
107 @Override
108 public void onPresencePacketReceived(Account account, PresencePacket packet) {
109 if (packet.hasChild("x", "http://jabber.org/protocol/muc#user")) {
110 this.parseConferencePresence(packet, account);
111 } else if (packet.hasChild("x", "http://jabber.org/protocol/muc")) {
112 this.parseConferencePresence(packet, account);
113 } else {
114 this.parseContactPresence(packet, account);
115 }
116 }
117
118}