1 /* 2 * libjingle 3 * Copyright 2011, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/xmpp/mucroomlookuptask.h" 29 30 #include "talk/base/logging.h" 31 #include "talk/base/scoped_ptr.h" 32 #include "talk/xmpp/constants.h" 33 34 35 namespace buzz { 36 37 MucRoomLookupTask* 38 MucRoomLookupTask::CreateLookupTaskForRoomName(XmppTaskParentInterface* parent, 39 const Jid& lookup_server_jid, 40 const std::string& room_name, 41 const std::string& room_domain) { 42 return new MucRoomLookupTask(parent, lookup_server_jid, 43 MakeNameQuery(room_name, room_domain)); 44 } 45 46 MucRoomLookupTask* 47 MucRoomLookupTask::CreateLookupTaskForRoomJid(XmppTaskParentInterface* parent, 48 const Jid& lookup_server_jid, 49 const Jid& room_jid) { 50 return new MucRoomLookupTask(parent, lookup_server_jid, 51 MakeJidQuery(room_jid)); 52 } 53 54 MucRoomLookupTask* 55 MucRoomLookupTask::CreateLookupTaskForHangoutId(XmppTaskParentInterface* parent, 56 const Jid& lookup_server_jid, 57 const std::string& hangout_id) { 58 return new MucRoomLookupTask(parent, lookup_server_jid, 59 MakeHangoutIdQuery(hangout_id)); 60 } 61 62 MucRoomLookupTask* 63 MucRoomLookupTask::CreateLookupTaskForExternalId( 64 XmppTaskParentInterface* parent, 65 const Jid& lookup_server_jid, 66 const std::string& external_id, 67 const std::string& type) { 68 return new MucRoomLookupTask(parent, lookup_server_jid, 69 MakeExternalIdQuery(external_id, type)); 70 } 71 72 MucRoomLookupTask::MucRoomLookupTask(XmppTaskParentInterface* parent, 73 const Jid& lookup_server_jid, 74 XmlElement* query) 75 : IqTask(parent, STR_SET, lookup_server_jid, query) { 76 } 77 78 XmlElement* MucRoomLookupTask::MakeNameQuery( 79 const std::string& room_name, const std::string& room_domain) { 80 XmlElement* name_elem = new XmlElement(QN_SEARCH_ROOM_NAME, false); 81 name_elem->SetBodyText(room_name); 82 83 XmlElement* domain_elem = new XmlElement(QN_SEARCH_ROOM_DOMAIN, false); 84 domain_elem->SetBodyText(room_domain); 85 86 XmlElement* query = new XmlElement(QN_SEARCH_QUERY, true); 87 query->AddElement(name_elem); 88 query->AddElement(domain_elem); 89 return query; 90 } 91 92 XmlElement* MucRoomLookupTask::MakeJidQuery(const Jid& room_jid) { 93 XmlElement* jid_elem = new XmlElement(QN_SEARCH_ROOM_JID); 94 jid_elem->SetBodyText(room_jid.Str()); 95 96 XmlElement* query = new XmlElement(QN_SEARCH_QUERY); 97 query->AddElement(jid_elem); 98 return query; 99 } 100 101 XmlElement* MucRoomLookupTask::MakeExternalIdQuery( 102 const std::string& external_id, const std::string& type) { 103 XmlElement* external_id_elem = new XmlElement(QN_SEARCH_EXTERNAL_ID); 104 external_id_elem->SetAttr(QN_TYPE, type); 105 external_id_elem->SetBodyText(external_id); 106 107 XmlElement* query = new XmlElement(QN_SEARCH_QUERY); 108 query->AddElement(external_id_elem); 109 return query; 110 } 111 112 // Construct a stanza to lookup the muc jid for a given hangout id. eg: 113 // 114 // <query xmlns="jabber:iq:search"> 115 // <hangout-id>0b48ad092c893a53b7bfc87422caf38e93978798e</hangout-id> 116 // </query> 117 XmlElement* MucRoomLookupTask::MakeHangoutIdQuery( 118 const std::string& hangout_id) { 119 XmlElement* hangout_id_elem = new XmlElement(QN_SEARCH_HANGOUT_ID, false); 120 hangout_id_elem->SetBodyText(hangout_id); 121 122 XmlElement* query = new XmlElement(QN_SEARCH_QUERY, true); 123 query->AddElement(hangout_id_elem); 124 return query; 125 } 126 127 // Handle a response like the following: 128 // 129 // <query xmlns="jabber:iq:search"> 130 // <item jid="muvc-private-chat-guid (at) groupchat.google.com"> 131 // <room-name>0b48ad092c893a53b7bfc87422caf38e93978798e</room-name> 132 // <room-domain>hangout.google.com</room-domain> 133 // </item> 134 // </query> 135 void MucRoomLookupTask::HandleResult(const XmlElement* stanza) { 136 const XmlElement* query_elem = stanza->FirstNamed(QN_SEARCH_QUERY); 137 if (query_elem == NULL) { 138 SignalError(this, stanza); 139 return; 140 } 141 142 const XmlElement* item_elem = query_elem->FirstNamed(QN_SEARCH_ITEM); 143 if (item_elem == NULL) { 144 SignalError(this, stanza); 145 return; 146 } 147 148 MucRoomInfo room; 149 room.jid = Jid(item_elem->Attr(buzz::QN_JID)); 150 if (!room.jid.IsValid()) { 151 SignalError(this, stanza); 152 return; 153 } 154 155 const XmlElement* room_name_elem = 156 item_elem->FirstNamed(QN_SEARCH_ROOM_NAME); 157 if (room_name_elem != NULL) { 158 room.name = room_name_elem->BodyText(); 159 } 160 161 const XmlElement* room_domain_elem = 162 item_elem->FirstNamed(QN_SEARCH_ROOM_DOMAIN); 163 if (room_domain_elem != NULL) { 164 room.domain = room_domain_elem->BodyText(); 165 } 166 167 const XmlElement* hangout_id_elem = 168 item_elem->FirstNamed(QN_SEARCH_HANGOUT_ID); 169 if (hangout_id_elem != NULL) { 170 room.hangout_id = hangout_id_elem->BodyText(); 171 } 172 173 SignalResult(this, room); 174 } 175 176 } // namespace buzz 177