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 final Jid jid = item.getAttributeAsJid("jid");
29 if (jid == null) {
30 continue;
31 }
32 String name = item.getAttribute("name");
33 String subscription = item.getAttribute("subscription");
34 Contact contact = account.getRoster().getContact(jid);
35 if (!contact.getOption(Contact.Options.DIRTY_PUSH)) {
36 contact.setServerName(name);
37 contact.parseGroupsFromElement(item);
38 }
39 if (subscription != null) {
40 if (subscription.equals("remove")) {
41 contact.resetOption(Contact.Options.IN_ROSTER);
42 contact.resetOption(Contact.Options.DIRTY_DELETE);
43 contact.resetOption(Contact.Options.PREEMPTIVE_GRANT);
44 } else {
45 contact.setOption(Contact.Options.IN_ROSTER);
46 contact.resetOption(Contact.Options.DIRTY_PUSH);
47 contact.parseSubscriptionFromElement(item);
48 }
49 }
50 mXmppConnectionService.getAvatarService().clear(contact);
51 }
52 }
53 mXmppConnectionService.updateConversationUi();
54 mXmppConnectionService.updateRosterUi();
55 }
56
57 public String avatarData(IqPacket packet) {
58 Element pubsub = packet.findChild("pubsub",
59 "http://jabber.org/protocol/pubsub");
60 if (pubsub == null) {
61 return null;
62 }
63 Element items = pubsub.findChild("items");
64 if (items == null) {
65 return null;
66 }
67 return super.avatarData(items);
68 }
69
70 @Override
71 public void onIqPacketReceived(Account account, IqPacket packet) {
72 if (packet.hasChild("query", "jabber:iq:roster")) {
73 final Jid from = packet.getFrom();
74 if ((from == null) || (from.equals(account.getJid().toBareJid()))) {
75 Element query = packet.findChild("query");
76 this.rosterItems(account, query);
77 }
78 } else {
79 if (packet.getFrom() == null) {
80 Log.d(Config.LOGTAG, account.getJid().toBareJid().toString() + ": received iq with invalid from "+packet.toString());
81 return;
82 } else if (packet.hasChild("open", "http://jabber.org/protocol/ibb")
83 || packet.hasChild("data", "http://jabber.org/protocol/ibb")) {
84 mXmppConnectionService.getJingleConnectionManager()
85 .deliverIbbPacket(account, packet);
86 } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
87 IqPacket response = mXmppConnectionService.getIqGenerator()
88 .discoResponse(packet);
89 account.getXmppConnection().sendIqPacket(response, null);
90 } else if (packet.hasChild("ping", "urn:xmpp:ping")) {
91 IqPacket response = packet.generateRespone(IqPacket.TYPE_RESULT);
92 mXmppConnectionService.sendIqPacket(account, response, null);
93 } else {
94 if ((packet.getType() == IqPacket.TYPE_GET)
95 || (packet.getType() == IqPacket.TYPE_SET)) {
96 IqPacket response = packet.generateRespone(IqPacket.TYPE_ERROR);
97 Element error = response.addChild("error");
98 error.setAttribute("type", "cancel");
99 error.addChild("feature-not-implemented",
100 "urn:ietf:params:xml:ns:xmpp-stanzas");
101 account.getXmppConnection().sendIqPacket(response, null);
102 }
103 }
104 }
105 }
106
107}