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 mXmppConnectionService.getAvatarService().clear(contact);
54 }
55 }
56 mXmppConnectionService.updateConversationUi();
57 mXmppConnectionService.updateRosterUi();
58 }
59
60 public String avatarData(IqPacket packet) {
61 Element pubsub = packet.findChild("pubsub",
62 "http://jabber.org/protocol/pubsub");
63 if (pubsub == null) {
64 return null;
65 }
66 Element items = pubsub.findChild("items");
67 if (items == null) {
68 return null;
69 }
70 return super.avatarData(items);
71 }
72
73 @Override
74 public void onIqPacketReceived(Account account, IqPacket packet) {
75 if (packet.hasChild("query", "jabber:iq:roster")) {
76 final Jid from = packet.getFrom();
77 if ((from == null) || (from.equals(account.getJid().toBareJid()))) {
78 Element query = packet.findChild("query");
79 this.rosterItems(account, query);
80 }
81 } else {
82 if (packet.getFrom() == null) {
83 Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString());
84 return;
85 } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
86 || packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
87 mXmppConnectionService.getJingleConnectionManager()
88 .deliverIbbPacket(account, packet);
89 } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
90 IqPacket response = mXmppConnectionService.getIqGenerator()
91 .discoResponse(packet);
92 account.getXmppConnection().sendIqPacket(response, null);
93 } else if (packet.hasChild("ping", "urn:xmpp:ping")) {
94 IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
95 mXmppConnectionService.sendIqPacket(account, response, null);
96 } else {
97 if ((packet.getType() == IqPacket.TYPE_GET)
98 || (packet.getType() == IqPacket.TYPE_SET)) {
99 IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR);
100 Element error = response.addChild("error");
101 error.setAttribute("type", "cancel");
102 error.addChild("feature-not-implemented",
103 "urn:ietf:params:xml:ns:xmpp-stanzas");
104 account.getXmppConnection().sendIqPacket(response, null);
105 }
106 }
107 }
108 }
109
110}