source: perl/lib/Net/XMPP/Roster.pm @ 4ee1cf4

barnowl_perlaimdebianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 4ee1cf4 was 72a53e9, checked in by Alejandro R. Sedeño <asedeno@mit.edu>, 14 years ago
Update to Roster.pm to not blow away presence information for a jid on every roster update for that jid.
  • Property mode set to 100644
File size: 25.2 KB
Line 
1##############################################################################
2#
3#  This library is free software; you can redistribute it and/or
4#  modify it under the terms of the GNU Library General Public
5#  License as published by the Free Software Foundation; either
6#  version 2 of the License, or (at your option) any later version.
7#
8#  This library is distributed in the hope that it will be useful,
9#  but WITHOUT ANY WARRANTY; without even the implied warranty of
10#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11#  Library General Public License for more details.
12#
13#  You should have received a copy of the GNU Library General Public
14#  License along with this library; if not, write to the
15#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
16#  Boston, MA  02111-1307, USA.
17#
18#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
19#
20##############################################################################
21
22package Net::XMPP::Roster;
23
24=head1 NAME
25
26Net::XMPP::Roster - XMPP Roster Object
27
28=head1 SYNOPSIS
29
30  Net::XMPP::Roster is a module that provides a developer an easy
31  interface to an XMPP roster.  It provides high level functions to
32  query, update, and manage a user's roster. 
33
34=head1 DESCRIPTION
35
36  The Roster object seeks to provide an easy to use API for interfacing
37  with a user's roster.  When you instantiate it, it automatically
38  registers with the connection to receivce the correct packets so
39  that it can track all roster updates, and presence packets.
40 
41=head2 Basic Functions
42
43  my $Client = new Net::XMPP::Client(...);
44
45  my $Roster = new Net::XMPP::Roster(connection=>$Client);
46    or
47  my $Roster = $Client->Roster();
48
49  $Roster->clear();
50
51  if ($Roster->exists('bob@jabber.org')) { ... }
52  if ($Roster->exists(Net::XMPP::JID)) { ... }
53
54  if ($Roster->groupExists("Friends")) { ... }
55
56  my @groups = $Roster->groups();
57
58  my @jids    = $Roster->jids();
59  my @friends = $Roster->jids("group","Friends");
60  my @unfiled = $Roster->jids("nogroup");
61
62  if ($Roster->online('bob@jabber.org')) { ... }
63  if ($Roster->online(Net::XMPP::JID)) { ... }
64
65  my %hash = $Roster->query('bob@jabber.org');
66  my %hash = $Roster->query(Net::XMPP::JID);
67
68  my $name = $Roster->query('bob@jabber.org',"name");
69  my $ask  = $Roster->query(Net::XMPP::JID,"ask");
70
71  my $resource = $Roster->resource('bob@jabber.org');
72  my $resource = $Roster->resource(Net::XMPP::JID);
73
74  my %hash = $Roster->resourceQuery('bob@jabber.org',"Home");
75  my %hash = $Roster->resourceQuery(Net::XMPP::JID,"Club");
76
77  my $show   = $Roster->resourceQuery('bob@jabber.org',"Home","show");
78  my $status = $Roster->resourceQuery(Net::XMPP::JID,"Work","status");
79
80  my @resource = $Roster->resources('bob@jabber.org');
81  my @resource = $Roster->resources(Net::XMPP::JID);
82
83  $Roster->resourceStore('bob@jabber.org',"Home","gpgkey",key);
84  $Roster->resourceStore(Net::XMPP::JID,"logged on","2004/04/07 ...");
85
86  $Roster->store('bob@jabber.org',"avatar",avatar);
87  $Roster->store(Net::XMPP::JID,"display_name","Bob");
88
89=head2 Advanced Functions
90
91  These functions are only needed if you want to manually control
92  the Roster.
93 
94  $Roster->add('bob@jabber.org',
95               name=>"Bob",
96               groups=>["Friends"]
97              );
98  $Roster->add(Net::XMPP::JID);
99
100  $Roster->addResource('bob@jabber.org',
101                       "Home",
102                       show=>"dnd",
103                       status=>"Working"
104                      );
105  $Roster->addResource(Net::XMPP::JID,"Work");
106
107  $Roster->remove('bob@jabber.org');
108  $Roster->remove(Net::XMPP::JID);
109
110  $Roster->removeResource('bob@jabber.org',"Home");
111  $Roster->removeResource(Net::XMPP::JID,"Work");
112
113  $Roster->handler(Net::XMPP::IQ);
114  $Roster->handler(Net::XMPP::Presence);
115
116=head1 METHODS
117
118=head2 Basic Functions
119
120
121  new(connection=>object) - This creates and initializes the Roster
122                            object.  The connection object is required
123                            so that the Roster can interact with the
124                            main connection object.  It needs to be an
125                            object that inherits from
126                            Net::XMPP::Connection.
127
128  clear() - removes everything from the database.
129
130  exists(jid) - return 1 if the JID exists in the database, undef
131                otherwise.  The jid can either be a string, or a
132                Net::XMPP::JID object.
133               
134  groupExists(group) - return 1 if the group exists in the database,
135                       undef otherwise.
136
137  groups() - returns a list of all of the roster groups.
138
139  jids([type,    - returns a list of all of the matching JIDs.  The valid
140       [group]])   types are:
141
142                    all     - return all JIDs in the roster. (default)
143                    nogroup - return all JIDs not in a roster group.
144                    group   - return all of the JIDs in the specified
145                              roster group.
146
147  online(jid) - return 1 if the JID is online, undef otherwise.  The
148                jid can either be a string, or a Net::XMPP::JID object.
149
150  query(jid,   - return a hash representing all of the data in the
151        [key])   DB for this JID.  The jid can either be a string,
152                 or a Net::XMPP::JID object.  If you specify a key,
153                 then only the value for that key is returned.
154
155  resource(jid) - return the string representing the resource with the
156                  highest priority for the JID.  The jid can either be
157                  a string, or a Net::XMPP::JID object.
158
159  resourceQuery(jid,      - return a hash representing all of the data
160                resource,   the DB for the resource for this JID.  The
161                [key])      jid can either be a string, or a
162                            Net::XMPP::JID object.  If you specify a
163                            key, then only the value for that key is
164                            returned.
165
166  resources(jid) - returns the list of resources for the JID in order
167                   of highest priority to lowest priority.  The jid can
168                   either be a string, or a Net::XMPP::JID object.
169
170  resourceStore(jid,      - store the specified value in the DB under
171                resource,   the specified key for the resource for this
172                key,        JID.  The jid can either be a string, or a
173                value)      Net::XMPP::JID object.
174
175  store(jid,      - store the specified value in the DB under the
176        key,        specified key for this JID.  The jid can either
177        value)      be a string, or a Net::XMPP::JID object.
178
179
180
181=head2 Advanced Functions
182
183add(jid,                 - Manually adds the JID to the Roster with the
184    ask=>string,           specified roster item settings.  This does not
185    groups=>arrayref       handle subscribing to other users, only
186    name=>string,          manipulating the Roster object.  The jid
187    subscription=>string)  can either be a string or a Net::XMPP::JID.
188
189addResource(jid,            - Manually add the resource to the JID in the
190            resource,         Roster with the specified presence settings.
191            priority=>int,    This does not handle subscribing to other
192            show=>string,     users, only manipulating the Roster object.
193            status=>string)   The jid can either be a string or a
194                              Net::XMPP::JID.
195
196remove(jid) - Removes all reference to the JID from the Roster object.
197              The jid can either be a string or a Net::XMPP::JID.
198
199removeResource(jid,      - Removes the resource from the jid in the
200               resource)   Roster object.  The jid can either be a string
201                           or a Net::XMPP::JID.
202
203handler(packet) - Take either a Net::XMPP::IQ or Net::XMPP::Presence
204                  packet and parse them according to the rules of the
205                  Roster object.  Note, that it will only waste CPU time
206                  if you pass in IQs or Presences that are not roster
207                  related.
208
209=head1 AUTHOR
210
211Ryan Eatmon
212
213=head1 COPYRIGHT
214
215This module is free software; you can redistribute it and/or modify
216it under the same terms as Perl itself.
217
218=cut
219
220use strict;
221use Carp;
222
223sub new
224{
225    my $proto = shift;
226    my $self = { };
227
228    my %args;
229    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
230
231    if (!exists($args{connection}) ||
232        !$args{connection}->isa("Net::XMPP::Connection"))
233    {
234        croak("You must pass Net::XMPP::Roster a valid connection object.");
235    }
236
237    $self->{CONNECTION} = $args{connection};
238   
239    bless($self, $proto);
240
241    $self->init();
242   
243    return $self;
244}
245
246
247##############################################################################
248#
249# init - initialize the module to use the roster database
250#
251##############################################################################
252sub init
253{
254    my $self = shift;
255
256    $self->{CONNECTION}-> SetXPathCallBacks('/iq[@type="result" or @type="set"]/query[@xmlns="jabber:iq:roster"]'=>sub{ $self->handler(@_) });
257    $self->{CONNECTION}-> SetXPathCallBacks('/presence'=>sub{ $self->handler(@_) });
258}
259
260
261##############################################################################
262#
263# add - adds the entry to the Roster DB.
264#
265##############################################################################
266sub add
267{
268    my $self = shift;
269    my ($jid,%item) = @_;
270
271    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
272    if (exists $self->{JIDS}->{$jid})
273    {
274        foreach my $key (keys %item)
275        {
276            $self->{JIDS}->{$jid}->{$key} = $item{$key};
277        }
278    }
279    else
280    {
281        $self->{JIDS}->{$jid} = \%item;
282
283    }
284    foreach my $group (@{$item{groups}})
285    {
286        $self->{GROUPS}->{$group}->{$jid} = 1;
287    }
288}
289
290
291
292##############################################################################
293#
294# addResource - adds the resource to the JID in the Roster DB.
295#
296##############################################################################
297sub addResource
298{
299    my $self = shift;
300    my $jid = shift;
301    my $resource = shift;
302    my (%item) = @_;
303
304    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
305
306    my $priority = $item{priority};
307    $priority = 0 unless defined($priority);
308
309    $self->{CONNECTION}->{DEBUG}->Log3("Roster::addResource: add $jid/$resource with priority $priority to the DB");
310
311    my $loc = -1;
312    $self->{JIDS}->{$jid}->{priorities}->{$priority} = []
313        unless exists($self->{JIDS}->{$jid}->{priorities}->{$priority});
314    foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
315    {
316        $loc = $index
317            if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq $resource);
318    }
319    $loc = $#{$self->{JIDS}->{$jid}->{priorities}->{$priority}} + 1 if ($loc == -1);
320
321    $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority} = $priority;
322    $self->{JIDS}->{$jid}->{resources}->{$resource}->{status} = $item{status}
323        if exists($item{status});
324    $self->{JIDS}->{$jid}->{resources}->{$resource}->{show} = $item{show}
325        if exists($item{show});
326    $self->{JIDS}->{$jid}->{priorities}->{$priority}->[$loc]->{resource} = $resource;
327}
328
329
330###############################################################################
331#
332# clear - delete all of the JIDs from the DB completely.
333#
334###############################################################################
335sub clear
336{
337    my $self = shift;
338
339    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: clearing the database");
340    foreach my $jid ($self->jids())
341    {
342        $self->remove($jid);
343    }
344    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: database is empty");
345}
346
347
348##############################################################################
349#
350# exists - allows you to query if the JID exists in the Roster DB.
351#
352##############################################################################
353sub exists
354{
355    my $self = shift;
356    my ($jid) = @_;
357
358    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
359   
360    return unless exists($self->{JIDS});
361    return unless exists($self->{JIDS}->{$jid});
362    return 1;
363}
364
365
366sub fetch
367{
368    my $self = shift;
369
370    my %newroster = $self->{CONNECTION}->RosterGet();
371
372    $self->handleRoster(\%newroster);
373}
374
375
376##############################################################################
377#
378# groupExists - allows you to query if the group exists in the Roster
379#                       DB.
380#
381##############################################################################
382sub groupExists
383{
384    my $self = shift;
385    my ($group) = @_;
386
387    return unless exists($self->{GROUPS});
388    return unless exists($self->{GROUPS}->{$group});
389    return 1;
390}
391
392
393##############################################################################
394#
395# groups - returns a list of the current groups in your roster.
396#
397##############################################################################
398sub groups
399{
400    my $self = shift;
401
402    return () unless exists($self->{GROUPS});
403    return () if (scalar(keys(%{$self->{GROUPS}})) == 0);
404    return keys(%{$self->{GROUPS}});
405}
406
407
408##############################################################################
409#
410# handler - takes a packet and calls the correct handler.
411#
412##############################################################################
413sub handler
414{
415    my $self = shift;
416    my $sid = shift;
417    my $packet = shift;
418
419    $self->handleIQ($packet) if ($packet->GetTag() eq "iq");
420    $self->handlePresence($packet) if ($packet->GetTag() eq "presence");
421}
422
423
424##############################################################################
425#
426# handleIQ - takes an iq packet that contains roster, parses it, and puts
427#            the roster into the Roster DB.
428#
429##############################################################################
430sub handleIQ
431{
432    my $self = shift;
433    my $iq = shift;
434
435    my $type = $iq->GetType();
436    return unless (($type eq "set") || ($type eq "result"));
437
438    my %newroster = $self->{CONNECTION}->RosterParse($iq);
439
440    $self->handleRoster(\%newroster);
441}
442
443
444sub handleRoster
445{
446    my $self = shift;
447    my $roster = shift;
448
449    foreach my $jid (keys(%{$roster}))
450    {
451        if ($roster->{$jid}->{subscription} ne "remove")
452        {
453            $self->add($jid, %{$roster->{$jid}});
454        }
455        else
456        {
457            $self->remove($jid);
458        }
459    }
460}
461
462
463##############################################################################
464#
465# handlePresence - takes a presence packet and groks the presence.
466#
467##############################################################################
468sub handlePresence
469{
470    my $self = shift;
471    my $presence = shift;
472
473    my $type = $presence->GetType();
474    $type = "" unless defined($type);
475    return unless (($type eq "") ||
476                   ($type eq "available") ||
477                   ($type eq "unavailable"));
478
479    my $jid = $presence->GetFrom("jid");
480
481    my $resource = $jid->GetResource();
482    $resource = " " unless ($resource ne "");
483   
484    $jid = $jid->GetJID();
485    $jid = "" unless defined($jid);
486
487    return unless $self->exists($jid);
488    #XXX if it doesn't exist... is it us?
489    #XXX is this a presence based roster?
490
491    $self->{CONNECTION}->{DEBUG}->Log3("Roster::PresenceDBParse: fromJID(",$presence->GetFrom(),") resource($resource) type($type)");
492    $self->{CONNECTION}->{DEBUG}->Log4("Roster::PresenceDBParse: xml(",$presence->GetXML(),")");
493
494    $self->removeResource($jid,$resource);
495
496    if (($type eq "") || ($type eq "available"))
497    {
498        my %item;
499       
500        $item{priority} = $presence->GetPriority();
501        $item{priority} = 0 unless defined($item{priority});
502
503        $item{show} = $presence->GetShow();
504        $item{show} = "" unless defined($item{show});
505
506        $item{status} = $presence->GetStatus();
507        $item{status} = "" unless defined($item{status});
508
509        $self->addResource($jid,$resource,%item);
510    }
511}
512
513
514##############################################################################
515#
516# jids - returns a list of all of the JIDs in your roster.
517#
518##############################################################################
519sub jids
520{
521    my $self = shift;
522    my $type = shift;
523    my $group = shift;
524
525    $type = "all" unless defined($type);
526
527    my @jids;
528
529    if (($type eq "all") || ($type eq "nogroup"))
530    {
531        return () unless exists($self->{JIDS});
532        foreach my $jid (keys(%{$self->{JIDS}}))
533        {
534            next if (($type eq "nogroup") &&
535                     exists($self->{JIDS}->{$jid}->{groups}) &&
536                     ($#{$self->{JIDS}->{$jid}->{groups}} > -1));
537
538            push(@jids,new Net::XMPP::JID($jid));
539        }
540    }
541   
542    if ($type eq "group")
543    {
544        return () unless exists($self->{GROUPS});
545        if (defined($group) && $self->groupExists($group))
546        {
547            foreach my $jid (keys(%{$self->{GROUPS}->{$group}}))
548            {
549                push(@jids,new Net::XMPP::JID($jid));
550            }
551        }
552    }
553
554    return @jids;
555}
556
557
558###############################################################################
559#
560# online - returns if the jid is online or not.
561#
562###############################################################################
563sub online
564{
565    my $self = shift;
566    my $jid = shift;
567
568    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
569
570    return unless $self->exists($jid);
571
572    my @resources = $self->resources($jid);
573
574    return ($#resources > -1);
575}
576
577
578##############################################################################
579#
580# priority - return the highest priority for the jid, or for the specified
581#            resource.
582#
583##############################################################################
584sub priority
585{
586    my $self = shift;
587    my $jid = shift;
588    my $resource = shift;
589
590    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
591   
592    if (defined($resource))
593    {
594        return unless $self->resourceExists($jid,$resource);
595        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{priority});
596        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority};
597    }
598   
599    return unless exists($self->{JIDS}->{$jid}->{priorities});
600    my @priorities = sort{ $b <=> $a } keys(%{$self->{JIDS}->{$jid}->{priorities}});
601    return $priorities[0];
602}
603
604
605##############################################################################
606#
607# query - allows you to get one of the pieces of info from the Roster DB.
608#
609##############################################################################
610sub query
611{
612    my $self = shift;
613    my $jid = shift;
614    my $key = shift;
615
616    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
617   
618    return unless $self->exists($jid);
619    if (defined($key))
620    {
621        return unless exists($self->{JIDS}->{$jid}->{$key});
622        return $self->{JIDS}->{$jid}->{$key};
623    }
624    return %{$self->{JIDS}->{$jid}};
625}
626
627
628##############################################################################
629#
630# remove - removes the JID from the Roster DB.
631#
632##############################################################################
633sub remove
634{
635    my $self = shift;
636    my $jid = shift;
637
638    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
639
640    if ($self->exists($jid))
641    {
642        $self->{CONNECTION}->{DEBUG}->Log3("Roster::remove: deleting $jid from the DB");
643       
644        if (defined($self->query($jid,"groups")))
645        {
646            foreach my $group (@{$self->query($jid,"groups")})
647            {
648                delete($self->{GROUPS}->{$group}->{$jid});
649                delete($self->{GROUPS}->{$group})
650                    if (scalar(keys(%{$self->{GROUPS}->{$group}})) == 0);
651                delete($self->{GROUPS})
652                    if (scalar(keys(%{$self->{GROUPS}})) == 0);
653            }
654        }
655   
656        delete($self->{JIDS}->{$jid});
657        delete($self->{JIDS}) if (scalar(keys(%{$self->{JIDS}})) == 0);
658    }
659}
660
661
662##############################################################################
663#
664# removeResource - removes the resource from the JID from the Roster DB.
665#
666##############################################################################
667sub removeResource
668{
669    my $self = shift;
670    my $jid = shift;
671    my $resource = shift;
672
673    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
674
675    if ($self->resourceExists($jid,$resource))
676    {
677        $self->{CONNECTION}->{DEBUG}->Log3("Roster::removeResource: remove $jid/$resource from the DB");
678
679        my $oldPriority = $self->priority($jid,$resource);
680        $oldPriority = "" unless defined($oldPriority);
681
682        if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}))
683        {
684            my $loc = 0;
685            foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}})
686            {
687                $loc = $index
688                    if ($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}->[$index]->{resource} eq $resource);
689            }
690           
691            splice(@{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}},$loc,1);
692
693            delete($self->{JIDS}->{$jid}->{priorities}->{$oldPriority})
694                if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}) &&
695                    ($#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}} == -1));
696        }
697
698        delete($self->{JIDS}->{$jid}->{resources}->{$resource});
699
700    }
701}
702
703
704###############################################################################
705#
706# resource - retrieve the resource with the highest priority.
707#
708###############################################################################
709sub resource
710{
711    my $self = shift;
712    my $jid = shift;
713
714    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
715
716    return unless $self->exists($jid);
717
718    my $priority = $self->priority($jid);
719
720    return unless defined($priority);
721
722    return $self->{JIDS}->{$jid}->{priorities}->{$priority}->[0]->{resource};
723}
724
725
726##############################################################################
727#
728# resourceExists - check that the specified resource exists.
729#
730##############################################################################
731sub resourceExists
732{
733    my $self = shift;
734    my $jid = shift;
735    my $resource = shift;
736   
737    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
738
739    return unless $self->exists($jid);
740    return unless exists($self->{JIDS}->{$jid}->{resources});
741    return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource});
742}
743
744
745##############################################################################
746#
747# resourceQuery - allows you to get one of the pieces of info from the Roster
748#                 DB.
749#
750##############################################################################
751sub resourceQuery
752{
753    my $self = shift;
754    my $jid = shift;
755    my $resource = shift;
756    my $key = shift;
757
758    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
759   
760    return unless $self->resourceExists($jid,$resource);
761    if (defined($key))
762    {
763        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{$key});
764        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key};
765    }
766    return %{$self->{JIDS}->{$jid}->{resources}->{$resource};}
767}
768
769
770###############################################################################
771#
772# resources - returns a list of the resources from highest priority to lowest.
773#
774###############################################################################
775sub resources
776{
777    my $self = shift;
778    my $jid = shift;
779
780    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
781
782    return () unless $self->exists($jid);
783
784    my @resources;
785
786    foreach my $priority (sort {$b cmp $a} keys(%{$self->{JIDS}->{$jid}->{priorities}}))
787    {
788        foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
789        {
790            next if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq " ");
791            push(@resources,$self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource});
792        }
793    }
794    return @resources;
795}
796
797
798##############################################################################
799#
800# resourceStore - allows you to store anything on the item that you want to.
801#                 The only drawback is that when the item is removed, the data
802#                 is not kept.  You must restore it in the DB.
803#
804##############################################################################
805sub resourceStore
806{
807    my $self = shift;
808    my $jid = shift;
809    my $resource = shift;
810    my $key = shift;
811    my $value = shift;
812
813    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
814
815    return unless defined($key);
816    return unless defined($value);
817    return unless $self->resourceExists($jid,$resource);
818
819    $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key} = $value;
820}
821
822
823##############################################################################
824#
825# store - allows you to store anything on the item that you want to.  The
826#         only drawback is that when the item is removed, the data is not
827#         kept.  You must restore it in the DB.
828#
829##############################################################################
830sub store
831{
832    my $self = shift;
833    my $jid = shift;
834    my $key = shift;
835    my $value = shift;
836
837    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
838
839    return unless defined($key);
840    return unless defined($value);
841    return unless $self->exists($jid);
842
843    $self->{JIDS}->{$jid}->{$key} = $value;
844}
845
846
8471;
848
Note: See TracBrowser for help on using the repository browser.