~ubuntu-branches/ubuntu/vivid/ekiga/vivid-proposed

« back to all changes in this revision

Viewing changes to plugins/resource-list/rl-heap.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kilian Krause
  • Date: 2011-07-17 00:24:50 UTC
  • mfrom: (5.1.5 upstream) (7.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20110717002450-ytg3wsrc1ptd3153
Tags: 3.3.1-1
* New upstream release.
 - Required libpt-dev 2.10 and libopal-dev 3.10
* Fix debian/watch to catch new version
* Remove libnotify0.7.patch - included upstream
* Add libboost-dev and libboost-signals-dev to Build-Depends
* debian/rules: Don't install *.la files for new internal shared libs
* Fix Vcs URIs to point to correct desktop/experimental/ekiga tree

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* Ekiga -- A VoIP and Video-Conferencing application
 
3
 * Copyright (C) 2000-2009 Damien Sandras <dsandras@seconix.com>
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software Foundation,
 
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 
18
 *
 
19
 *
 
20
 * Ekiga is licensed under the GPL license and as a special exception,
 
21
 * you have permission to link or otherwise combine this program with the
 
22
 * programs OPAL, OpenH323 and PWLIB, and distribute the combination,
 
23
 * without applying the requirements of the GNU GPL to the OPAL, OpenH323
 
24
 * and PWLIB programs, as long as you do follow the requirements of the
 
25
 * GNU GPL for all the rest of the software thus combined.
 
26
 */
 
27
 
 
28
 
 
29
/*
 
30
 *                         rl-heap.cpp  -  description
 
31
 *                         ------------------------------------------
 
32
 *   begin                : written in 2008 by Julien Puydt
 
33
 *   copyright            : (c) 2008 by Julien Puydt
 
34
 *   description          : resource-list heap implementation
 
35
 *
 
36
 */
 
37
 
 
38
#include <glib/gi18n.h>
 
39
 
 
40
#include "robust-xml.h"
 
41
#include "form-request-simple.h"
 
42
#include "xcap-core.h"
 
43
 
 
44
#include "rl-heap.h"
 
45
 
 
46
RL::Heap::Heap (Ekiga::ServiceCore& services_,
 
47
                boost::shared_ptr<xmlDoc> doc_,
 
48
                xmlNodePtr node_):
 
49
  services(services_),
 
50
  node(node_), name(NULL),
 
51
  root(NULL), user(NULL),
 
52
  username(NULL), password(NULL),
 
53
  doc(doc_), list_node(NULL)
 
54
{
 
55
  {
 
56
    xmlChar* xml_str = NULL;
 
57
 
 
58
    xml_str = xmlGetProp (node, BAD_CAST "writable");
 
59
    if (xml_str != NULL)
 
60
      xmlFree (xml_str);
 
61
    else {
 
62
      xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
 
63
    }
 
64
  }
 
65
 
 
66
  for (xmlNodePtr child = node->children; child != NULL; child = child->next) {
 
67
 
 
68
    if (child->type == XML_ELEMENT_NODE
 
69
        && child->name != NULL) {
 
70
 
 
71
      if (xmlStrEqual (BAD_CAST ("name"), child->name)) {
 
72
 
 
73
        name = child;
 
74
        continue;
 
75
      }
 
76
      if (xmlStrEqual (BAD_CAST ("root"), child->name)) {
 
77
 
 
78
        root = child;
 
79
        continue;
 
80
      }
 
81
      if (xmlStrEqual (BAD_CAST ("user"), child->name)) {
 
82
 
 
83
        user = child;
 
84
        continue;
 
85
      }
 
86
      if (xmlStrEqual (BAD_CAST ("username"), child->name)) {
 
87
 
 
88
        username = child;
 
89
        continue;
 
90
      }
 
91
      if (xmlStrEqual (BAD_CAST ("password"), child->name)) {
 
92
 
 
93
        password = child;
 
94
        continue;
 
95
      }
 
96
    }
 
97
  }
 
98
 
 
99
  if (name == NULL)
 
100
    name = xmlNewChild (node, NULL, BAD_CAST "name",
 
101
                        BAD_CAST robust_xmlEscape(doc.get (),
 
102
                                                  _("Unnamed")).c_str ());
 
103
  if (root == NULL)
 
104
    root = xmlNewChild (node, NULL, BAD_CAST "root", BAD_CAST "");
 
105
  if (user == NULL)
 
106
    user = xmlNewChild (node, NULL, BAD_CAST "user", BAD_CAST "");
 
107
  if (username == NULL)
 
108
    username = xmlNewChild (node, NULL, BAD_CAST "username", BAD_CAST "");
 
109
  if (password == NULL)
 
110
    password = xmlNewChild (node, NULL, BAD_CAST "password", BAD_CAST "");
 
111
 
 
112
  refresh ();
 
113
}
 
114
 
 
115
RL::Heap::Heap (Ekiga::ServiceCore& services_,
 
116
                boost::shared_ptr<xmlDoc> doc_,
 
117
                const std::string name_,
 
118
                const std::string root_,
 
119
                const std::string user_,
 
120
                const std::string username_,
 
121
                const std::string password_,
 
122
                bool writable_):
 
123
  services(services_),
 
124
  node(NULL), name(NULL),
 
125
  root(NULL), user(NULL),
 
126
  username(NULL), password(NULL),
 
127
  doc(doc_), list_node(NULL)
 
128
{
 
129
  node = xmlNewNode (NULL, BAD_CAST "entry");
 
130
  if (writable_)
 
131
    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "1");
 
132
  else
 
133
    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
 
134
 
 
135
  if ( !name_.empty ())
 
136
    name = xmlNewChild (node, NULL,
 
137
                        BAD_CAST "name",
 
138
                        BAD_CAST robust_xmlEscape (node->doc,
 
139
                                                   name_).c_str ());
 
140
  else
 
141
    name = xmlNewChild (node, NULL,
 
142
                        BAD_CAST "name",
 
143
                        BAD_CAST robust_xmlEscape (node->doc,
 
144
                                                   _("Unnamed")).c_str ());
 
145
  root = xmlNewChild (node, NULL,
 
146
                      BAD_CAST "root",
 
147
                      BAD_CAST robust_xmlEscape (node->doc,
 
148
                                                 root_).c_str ());
 
149
  user = xmlNewChild (node, NULL,
 
150
                      BAD_CAST "user",
 
151
                      BAD_CAST robust_xmlEscape (node->doc,
 
152
                                                 user_).c_str ());
 
153
  username = xmlNewChild (node, NULL,
 
154
                          BAD_CAST "username",
 
155
                          BAD_CAST robust_xmlEscape (node->doc,
 
156
                                                     username_).c_str ());
 
157
  password = xmlNewChild (node, NULL,
 
158
                          BAD_CAST "password",
 
159
                          BAD_CAST robust_xmlEscape (node->doc,
 
160
                                                     password_).c_str ());
 
161
  refresh ();
 
162
}
 
163
 
 
164
RL::Heap::~Heap ()
 
165
{
 
166
}
 
167
 
 
168
const std::string
 
169
RL::Heap::get_name () const
 
170
{
 
171
  std::string result;
 
172
  xmlChar* str = xmlNodeGetContent (name);
 
173
  if (str != NULL)
 
174
    result = (const char*)str;
 
175
  else
 
176
    result = _("Unnamed");
 
177
 
 
178
  xmlFree (str);
 
179
 
 
180
  return result;
 
181
}
 
182
 
 
183
void
 
184
RL::Heap::visit_presentities (boost::function1<bool, Ekiga::PresentityPtr > visitor) const
 
185
{
 
186
  bool go_on = true;
 
187
 
 
188
  for (std::map<PresentityPtr,std::list<boost::signals::connection> >::const_iterator
 
189
         iter = presentities.begin ();
 
190
       go_on && iter != presentities.end ();
 
191
       ++iter)
 
192
    go_on = visitor (iter->first);
 
193
}
 
194
 
 
195
bool
 
196
RL::Heap::populate_menu (Ekiga::MenuBuilder& builder)
 
197
{
 
198
  builder.add_action ("add", _("_Add a new contact"),
 
199
                      boost::bind (&RL::Heap::new_entry, this));
 
200
  builder.add_action ("refresh", _("_Refresh contact list"),
 
201
                      boost::bind (&RL::Heap::refresh, this));
 
202
  builder.add_action ("properties", _("Contact list _properties"),
 
203
                      boost::bind (&RL::Heap::edit, this));
 
204
  return true;
 
205
}
 
206
 
 
207
bool
 
208
RL::Heap::populate_menu_for_group (std::string /*group*/,
 
209
                                   Ekiga::MenuBuilder& /*builder*/)
 
210
{
 
211
  return false; // FIXME
 
212
}
 
213
 
 
214
xmlNodePtr
 
215
RL::Heap::get_node () const
 
216
{
 
217
  return node;
 
218
}
 
219
 
 
220
void
 
221
RL::Heap::refresh ()
 
222
{
 
223
  boost::shared_ptr<XCAP::Core> xcap = services.get<XCAP::Core> ("xcap-core");
 
224
  std::string root_str;
 
225
  std::string username_str;
 
226
  std::string password_str;
 
227
  std::string user_str;
 
228
 
 
229
  {
 
230
    xmlChar* str = xmlNodeGetContent (root);
 
231
    if (str != NULL)
 
232
      root_str = (const char*)str;
 
233
  }
 
234
  {
 
235
    xmlChar* str = xmlNodeGetContent (user);
 
236
    if (str != NULL)
 
237
      user_str = (const char*)str;
 
238
  }
 
239
  {
 
240
    xmlChar* str = xmlNodeGetContent (username);
 
241
    if (str != NULL)
 
242
      username_str = (const char*)str;
 
243
  }
 
244
  {
 
245
    xmlChar* str = xmlNodeGetContent (password);
 
246
    if (str != NULL)
 
247
      password_str = (const char*)str;
 
248
  }
 
249
  boost::shared_ptr<XCAP::Path> path(new XCAP::Path (root_str, "resource-lists",
 
250
                                             user_str));
 
251
  path->set_credentials (username_str, password_str);
 
252
  path = path->build_child ("resource-lists");
 
253
 
 
254
  while ( !presentities.empty ()) {
 
255
 
 
256
    presentities.begin()->first->removed ();
 
257
    for (std::list<boost::signals::connection>::const_iterator iter2
 
258
           = presentities.begin()->second.begin ();
 
259
         iter2 != presentities.begin()->second.end ();
 
260
         ++iter2)
 
261
      iter2->disconnect ();
 
262
    presentities.erase (presentities.begin()->first);
 
263
  }
 
264
 
 
265
  doc.reset ();
 
266
 
 
267
  xcap->read (path, boost::bind (&RL::Heap::on_document_received, this, _1, _2));
 
268
}
 
269
 
 
270
void
 
271
RL::Heap::on_document_received (bool error,
 
272
                                std::string value)
 
273
{
 
274
  if (error) {
 
275
 
 
276
    // FIXME: do something
 
277
    std::cout << "XCAP error: " << value << std::endl;
 
278
  } else {
 
279
 
 
280
    parse_doc (value);
 
281
  }
 
282
}
 
283
 
 
284
void
 
285
RL::Heap::parse_doc (std::string raw)
 
286
{
 
287
  doc = boost::shared_ptr<xmlDoc> (xmlRecoverMemory (raw.c_str (), raw.length ()), xmlFreeDoc);
 
288
  if ( !doc)
 
289
    doc = boost::shared_ptr<xmlDoc> (xmlNewDoc (BAD_CAST "1.0"), xmlFreeDoc);
 
290
  xmlNodePtr doc_root = xmlDocGetRootElement (doc.get ());
 
291
 
 
292
  if (doc_root == NULL
 
293
      || doc_root->name == NULL
 
294
      || !xmlStrEqual (BAD_CAST "resource-lists", doc_root->name)) {
 
295
 
 
296
    std::cout << "Invalid document in " << __PRETTY_FUNCTION__ << std::endl;
 
297
    // FIXME: warn the user somehow?
 
298
    doc.reset ();
 
299
  } else {
 
300
 
 
301
 
 
302
    for (xmlNodePtr child = doc_root->children;
 
303
         child != NULL;
 
304
         child = child->next)
 
305
      if (child->type == XML_ELEMENT_NODE
 
306
          && child->name != NULL
 
307
          && xmlStrEqual (BAD_CAST ("list"), child->name)) {
 
308
 
 
309
        parse_list (child);
 
310
        break; // read only one!
 
311
      }
 
312
  }
 
313
}
 
314
 
 
315
void
 
316
RL::Heap::parse_list (xmlNodePtr list)
 
317
{
 
318
  std::string root_str;
 
319
  std::string user_str;
 
320
  std::string username_str;
 
321
  std::string password_str;
 
322
  bool writable = false;
 
323
 
 
324
  list_node = list;
 
325
  {
 
326
    xmlChar* str = xmlNodeGetContent (root);
 
327
    if (str != NULL)
 
328
      root_str = (const char*)str;
 
329
  }
 
330
  {
 
331
    xmlChar* str = xmlNodeGetContent (user);
 
332
    if (str != NULL)
 
333
      user_str = (const char*)str;
 
334
  }
 
335
  {
 
336
    xmlChar* str = xmlNodeGetContent (username);
 
337
    if (str != NULL)
 
338
      username_str = (const char*)str;
 
339
  }
 
340
  {
 
341
    xmlChar* str = xmlNodeGetContent (password);
 
342
    if (str != NULL)
 
343
      password_str = (const char*)str;
 
344
  }
 
345
  {
 
346
    xmlChar* str = xmlGetProp (node, BAD_CAST "writable");
 
347
    if (str != NULL) {
 
348
 
 
349
      if (xmlStrEqual (str, BAD_CAST "1"))
 
350
        writable = true;
 
351
      xmlFree (str);
 
352
    }
 
353
  }
 
354
 
 
355
  boost::shared_ptr<XCAP::Path> path(new XCAP::Path (root_str, "resource-lists",
 
356
                                             user_str));
 
357
  path->set_credentials (username_str, password_str);
 
358
  path = path->build_child ("resource-lists");
 
359
  path = path->build_child ("list");
 
360
 
 
361
  for (xmlNodePtr child = list->children;
 
362
       child != NULL;
 
363
       child = child->next)
 
364
    if (child->type == XML_ELEMENT_NODE
 
365
        && child->name != NULL
 
366
        && xmlStrEqual (BAD_CAST ("entry"), child->name)) {
 
367
 
 
368
      PresentityPtr presentity(new Presentity (services, path, doc, child, writable));
 
369
      std::list<boost::signals::connection> conns;
 
370
      conns.push_back (presentity->updated.connect (boost::bind (boost::ref (presentity_updated), presentity)));
 
371
      conns.push_back (presentity->removed.connect (boost::bind(boost::ref (presentity_removed),presentity)));
 
372
      conns.push_back (presentity->trigger_reload.connect (boost::bind (&RL::Heap::refresh, this)));
 
373
      conns.push_back (presentity->questions.connect (boost::ref (questions)));
 
374
      presentities[presentity]=conns;
 
375
      presentity_added (presentity);
 
376
      continue;
 
377
    }
 
378
}
 
379
 
 
380
void
 
381
RL::Heap::push_presence (const std::string uri_,
 
382
                         const std::string presence)
 
383
{
 
384
  for (std::map<PresentityPtr,std::list<boost::signals::connection> >::const_iterator
 
385
         iter = presentities.begin ();
 
386
       iter != presentities.end ();
 
387
       ++iter) {
 
388
 
 
389
    if (iter->first->get_uri () == uri_)
 
390
      iter->first->set_presence (presence);
 
391
  }
 
392
}
 
393
 
 
394
void
 
395
RL::Heap::push_status (const std::string uri_,
 
396
                       const std::string status)
 
397
{
 
398
  for (std::map<PresentityPtr,std::list<boost::signals::connection> >::const_iterator
 
399
         iter = presentities.begin ();
 
400
       iter != presentities.end ();
 
401
       ++iter) {
 
402
 
 
403
    if (iter->first->get_uri () == uri_)
 
404
      iter->first->set_status (status);
 
405
  }
 
406
}
 
407
 
 
408
void
 
409
RL::Heap::edit ()
 
410
{
 
411
  boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&RL::Heap::on_edit_form_submitted, this, _1, _2)));
 
412
 
 
413
  std::string name_str;
 
414
  std::string root_str;
 
415
  std::string username_str;
 
416
  std::string password_str;
 
417
  std::string user_str;
 
418
  bool writable = false;
 
419
 
 
420
  {
 
421
    xmlChar* str = xmlNodeGetContent (root);
 
422
    if (str != NULL) {
 
423
 
 
424
      root_str = (const char*)str;
 
425
      xmlFree (str);
 
426
    }
 
427
  }
 
428
  {
 
429
    xmlChar* str = xmlNodeGetContent (user);
 
430
    if (str != NULL) {
 
431
 
 
432
      user_str = (const char*)str;
 
433
      xmlFree (str);
 
434
    }
 
435
  }
 
436
  {
 
437
    xmlChar* str = xmlNodeGetContent (username);
 
438
    if (str != NULL) {
 
439
 
 
440
      username_str = (const char*)str;
 
441
      xmlFree (str);
 
442
    }
 
443
  }
 
444
  {
 
445
    xmlChar* str = xmlNodeGetContent (password);
 
446
    if (str != NULL) {
 
447
 
 
448
      password_str = (const char*)str;
 
449
      xmlFree (str);
 
450
    }
 
451
  }
 
452
  {
 
453
    xmlChar* str = xmlGetProp (node, BAD_CAST "writable");
 
454
    if (str != NULL) {
 
455
 
 
456
      if (xmlStrEqual (str, BAD_CAST "1"))
 
457
        writable = true;
 
458
      xmlFree (str);
 
459
    }
 
460
  }
 
461
 
 
462
  request->title (_("Edit contact list properties"));
 
463
 
 
464
  request->instructions (_("Please edit the following fields (no identifier"
 
465
                           " means global)"));
 
466
 
 
467
  request->text ("name", _("Contact list's name:"), get_name (), std::string ());
 
468
  /* "Document" used as a name -- uri point to the root of a document tree */
 
469
  request->text ("root", _("Document root:"), root_str, std::string ());
 
470
  request->text ("user", _("Identifier:"), user_str, std::string ());
 
471
  request->boolean ("writable", _("Writable:"), writable);
 
472
  request->text ("username", _("Server username:"), username_str, std::string ());
 
473
  request->private_text ("password", _("Server password:"), password_str, std::string ());
 
474
 
 
475
  questions (request);
 
476
}
 
477
 
 
478
void
 
479
RL::Heap::on_edit_form_submitted (bool submitted,
 
480
                                  Ekiga::Form& result)
 
481
{
 
482
  if (!submitted)
 
483
    return;
 
484
 
 
485
  std::string name_str = result.text ("name");
 
486
  std::string root_str = result.text ("root");
 
487
  std::string user_str = result.text ("user");
 
488
  std::string username_str = result.text ("username");
 
489
  std::string password_str = result.private_text ("password");
 
490
  bool writable = result.boolean ("writable");
 
491
 
 
492
  if (writable)
 
493
    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "1");
 
494
  else
 
495
    xmlSetProp (node, BAD_CAST "writable", BAD_CAST "0");
 
496
  robust_xmlNodeSetContent (node, &name, "name", name_str);
 
497
  robust_xmlNodeSetContent (node, &root, "root", root_str);
 
498
  robust_xmlNodeSetContent (node, &user, "user", user_str);
 
499
  robust_xmlNodeSetContent (node, &username, "username", username_str);
 
500
  robust_xmlNodeSetContent (node, &password, "password", password_str);
 
501
 
 
502
  trigger_saving ();
 
503
  updated ();
 
504
  refresh ();
 
505
}
 
506
 
 
507
void
 
508
RL::Heap::new_entry ()
 
509
{
 
510
  boost::shared_ptr<Ekiga::FormRequestSimple> request = boost::shared_ptr<Ekiga::FormRequestSimple> (new Ekiga::FormRequestSimple (boost::bind (&RL::Heap::on_new_entry_form_submitted, this, _1, _2)));
 
511
 
 
512
  request->title (_("Add a remote contact"));
 
513
  request->instructions (_("Please fill in this form to create a new "
 
514
                           "contact on a remote server"));
 
515
 
 
516
  std::set<std::string> all_groups;
 
517
  for (std::map<PresentityPtr,std::list<boost::signals::connection> >::const_iterator
 
518
         iter = presentities.begin ();
 
519
       iter != presentities.end ();
 
520
       ++iter) {
 
521
 
 
522
    std::set<std::string> groups = iter->first->get_groups ();
 
523
    all_groups.insert (groups.begin (), groups.end ());
 
524
  }
 
525
 
 
526
  request->text ("name", _("Name:"), "", std::string ());
 
527
  request->text ("uri", _("Address:"), "", std::string ());
 
528
  request->editable_set ("groups", _("Choose groups:"),
 
529
                         std::set<std::string>(), all_groups);
 
530
 
 
531
  questions (request);
 
532
}
 
533
 
 
534
void
 
535
RL::Heap::on_new_entry_form_submitted (bool submitted,
 
536
                                       Ekiga::Form& result)
 
537
{
 
538
  if (!submitted)
 
539
    return;
 
540
 
 
541
  std::string entry_name = result.text ("name");
 
542
  std::string entry_uri = result.text ("uri");
 
543
  std::set<std::string> entry_groups = result.editable_set ("groups");
 
544
 
 
545
  xmlNodePtr entry_node = xmlNewChild (list_node, NULL,
 
546
                                       BAD_CAST "entry", NULL);
 
547
  xmlSetProp (entry_node, BAD_CAST "uri",
 
548
              BAD_CAST robust_xmlEscape (doc.get (), entry_uri).c_str ());
 
549
  xmlNewChild (entry_node, NULL, BAD_CAST "display-name",
 
550
               BAD_CAST robust_xmlEscape (doc.get (), entry_name).c_str ());
 
551
  xmlNsPtr ns = xmlSearchNsByHref (doc.get (), entry_node,
 
552
                                   BAD_CAST "http://www.ekiga.org");
 
553
  if (ns == NULL) {
 
554
 
 
555
    // FIXME: we should handle the case, even if it shouldn't happen
 
556
  }
 
557
 
 
558
  for (std::set<std::string>::const_iterator iter = entry_groups.begin ();
 
559
       iter != entry_groups.end ();
 
560
       ++iter) {
 
561
 
 
562
    xmlNewChild (entry_node, ns, BAD_CAST "group",
 
563
                 BAD_CAST robust_xmlEscape (doc.get (), *iter).c_str ());
 
564
  }
 
565
 
 
566
  xmlBufferPtr buffer = xmlBufferCreate ();
 
567
  int res = xmlNodeDump (buffer, doc.get (), entry_node, 0, 0);
 
568
 
 
569
  if (res >= 0) {
 
570
 
 
571
    std::string root_str;
 
572
    std::string username_str;
 
573
    std::string password_str;
 
574
    std::string user_str;
 
575
 
 
576
    {
 
577
      xmlChar* str = xmlNodeGetContent (root);
 
578
      if (str != NULL)
 
579
        root_str = (const char*)str;
 
580
    }
 
581
    {
 
582
      xmlChar* str = xmlNodeGetContent (user);
 
583
      if (str != NULL)
 
584
        user_str = (const char*)str;
 
585
    }
 
586
    {
 
587
      xmlChar* str = xmlNodeGetContent (username);
 
588
      if (str != NULL)
 
589
        username_str = (const char*)str;
 
590
    }
 
591
    {
 
592
      xmlChar* str = xmlNodeGetContent (password);
 
593
      if (str != NULL)
 
594
        password_str = (const char*)str;
 
595
    }
 
596
    boost::shared_ptr<XCAP::Path> path(new XCAP::Path (root_str, "resource-lists",
 
597
                                               user_str));
 
598
    path->set_credentials (username_str, password_str);
 
599
    path = path->build_child ("resource-lists");
 
600
    path = path->build_child ("list");
 
601
    path = path->build_child_with_attribute ("entry", "uri", entry_uri);
 
602
    boost::shared_ptr<XCAP::Core> xcap = services.get<XCAP::Core> ("xcap-core");
 
603
    xcap->write (path, "application/xcap-el+xml",
 
604
                 (const char*)xmlBufferContent (buffer),
 
605
                 boost::bind (&RL::Heap::new_entry_result, this, _1));
 
606
  }
 
607
  xmlBufferFree (buffer);
 
608
}
 
609
 
 
610
void
 
611
RL::Heap::new_entry_result (std::string error)
 
612
{
 
613
  if ( !error.empty ()) {
 
614
 
 
615
    std::cout << "XCAP Error: " << error << std::endl;
 
616
  }
 
617
 
 
618
  refresh ();
 
619
}