1package eu.siacs.conversations.parser;
2
3import android.util.Log;
4
5import eu.siacs.conversations.Config;
6import eu.siacs.conversations.entities.Account;
7import eu.siacs.conversations.entities.Contact;
8import eu.siacs.conversations.services.XmppConnectionService;
9import eu.siacs.conversations.xml.Element;
10import eu.siacs.conversations.xmpp.OnIqPacketReceived;
11import eu.siacs.conversations.xmpp.jid.InvalidJidException;
12import eu.siacs.conversations.xmpp.jid.Jid;
13import eu.siacs.conversations.xmpp.stanzas.IqPacket;
14
15public class IqParser extends AbstractParser implements OnIqPacketReceived {
16
17 public IqParser(XmppConnectionService service) {
18 super(service);
19 }
20
21 public void rosterItems(Account account, Element query) {
22 String version = query.getAttribute("ver");
23 if (version != null) {
24 account.getRoster().setVersion(version);
25 }
26 for (Element item : query.getChildren()) {
27 if (item.getName().equals("item")) {
28 Jid jid;
29 try {
30 jid = Jid.fromString(item.getAttribute("jid"));
31 } catch (final InvalidJidException e) {
32 // TODO: Handle this?
33 jid = null;
34 }
35 String name = item.getAttribute("name");
36 String subscription = item.getAttribute("subscription");
37 Contact contact = account.getRoster().getContact(jid);
38 if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
39 contact.setServerName(name);
40 contact.parseGroupsFromElement(item);
41 }
42 if (subscription != null) {
43 if (subscription.equals("remove")) {
44 contact.resetOption(Contact.Options.IN_ROSTER);
45 contact.resetOption(Contact.Options.DIRTY_DELETE);
46 contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
47 } else {
48 contact.setOption(Contact.Options.IN_ROSTER);
49 contact.resetOption(Contact.Options.DIRTY_PUSH);
50 contact.parseSubscriptionFromElement(item);
51 }
52 }
53 }
54 }
55 mXmppConnectionService.updateRosterUi();
56 }
57
58 public String avatarData(IqPacket packet) {
59 Element pubsub = packet.findChild("pubsub",
60 "http://jabber.org/protocol/pubsub");
61 if (pubsub == null) {
62 return null;
63 }
64 Element items = pubsub.findChild("items");
65 if (items == null) {
66 return null;
67 }
68 return super.avatarData(items);
69 }
70
71 @Override
72 public void onIqPacketReceived(Account account, IqPacket packet) {
73 if (packet.hasChild("query", "jabber:iq:roster")) {
74 final Jid from = packet.getFrom();
75 if ((from == null) || (from.equals(account.getJid().toBareJid()))) {
76 Element query = packet.findChild("query");
77 this.rosterItems(account, query);
78 }
79 } else {
80 if (packet.getFrom() == null) {
81 Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString());
82 return;
83 } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
84 || packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
85 mXmppConnectionService.getJingleConnectionManager()
86 .deliverIbbPacket(account, packet);
87 } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
88 IqPacket response = mXmppConnectionService.getIqGenerator()
89 .discoResponse(packet);
90 account.getXmppConnection().sendIqPacket(response, null);
91 } else if (packet.hasChild("ping", "urn:xmpp:ping")) {
92 IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
93 mXmppConnectionService.sendIqPacket(account, response, null);
94 } else {
95 if ((packet.getType() == IqPacket.TYPE_GET)
96 || (packet.getType() == IqPacket.TYPE_SET)) {
97 IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR);
98 Element error = response.addChild("error");
99 error.setAttribute("type", "cancel");
100 error.addChild("feature-not-implemented",
101 "urn:ietf:params:xml:ns:xmpp-stanzas");
102 account.getXmppConnection().sendIqPacket(response, null);
103 }
104 }
105 }
106 }
107
108}