source: perl/lib/Net/XMPP/Roster.pm @ 0ff8d110

barnowl_perlaimdebianrelease-1.4release-1.5release-1.6release-1.7release-1.8release-1.9
Last change on this file since 0ff8d110 was 0ff8d110, checked in by Alejandro R. Sedeño <asedeno@mit.edu>, 15 years ago
Adding XML::Stream, Net::XMPP, and Net::Jabber to perl/lib/
  • Property mode set to 100644
File size: 25.0 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 $jid->isa("Net::XMPP::JID");
272
273    $self->{JIDS}->{$jid} = \%item;
274
275    foreach my $group (@{$item{groups}})
276    {
277        $self->{GROUPS}->{$group}->{$jid} = 1;
278    }
279}
280
281
282
283##############################################################################
284#
285# addResource - adds the resource to the JID in the Roster DB.
286#
287##############################################################################
288sub addResource
289{
290    my $self = shift;
291    my $jid = shift;
292    my $resource = shift;
293    my (%item) = @_;
294
295    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
296
297    my $priority = $item{priority};
298    $priority = 0 unless defined($priority);
299
300    $self->{CONNECTION}->{DEBUG}->Log3("Roster::addResource: add $jid/$resource with priority $priority to the DB");
301
302    my $loc = -1;
303    $self->{JIDS}->{$jid}->{priorities}->{$priority} = []
304        unless exists($self->{JIDS}->{$jid}->{priorities}->{$priority});
305    foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
306    {
307        $loc = $index
308            if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq $resource);
309    }
310    $loc = $#{$self->{JIDS}->{$jid}->{priorities}->{$priority}} + 1 if ($loc == -1);
311
312    $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority} = $priority;
313    $self->{JIDS}->{$jid}->{resources}->{$resource}->{status} = $item{status}
314        if exists($item{status});
315    $self->{JIDS}->{$jid}->{resources}->{$resource}->{show} = $item{show}
316        if exists($item{show});
317    $self->{JIDS}->{$jid}->{priorities}->{$priority}->[$loc]->{resource} = $resource;
318}
319
320
321###############################################################################
322#
323# clear - delete all of the JIDs from the DB completely.
324#
325###############################################################################
326sub clear
327{
328    my $self = shift;
329
330    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: clearing the database");
331    foreach my $jid ($self->jids())
332    {
333        $self->remove($jid);
334    }
335    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: database is empty");
336}
337
338
339##############################################################################
340#
341# exists - allows you to query if the JID exists in the Roster DB.
342#
343##############################################################################
344sub exists
345{
346    my $self = shift;
347    my ($jid) = @_;
348
349    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
350   
351    return unless exists($self->{JIDS});
352    return unless exists($self->{JIDS}->{$jid});
353    return 1;
354}
355
356
357sub fetch
358{
359    my $self = shift;
360
361    my %newroster = $self->{CONNECTION}->RosterGet();
362
363    $self->handleRoster(\%newroster);
364}
365
366
367##############################################################################
368#
369# groupExists - allows you to query if the group exists in the Roster
370#                       DB.
371#
372##############################################################################
373sub groupExists
374{
375    my $self = shift;
376    my ($group) = @_;
377
378    return unless exists($self->{GROUPS});
379    return unless exists($self->{GROUPS}->{$group});
380    return 1;
381}
382
383
384##############################################################################
385#
386# groups - returns a list of the current groups in your roster.
387#
388##############################################################################
389sub groups
390{
391    my $self = shift;
392
393    return () unless exists($self->{GROUPS});
394    return () if (scalar(keys(%{$self->{GROUPS}})) == 0);
395    return keys(%{$self->{GROUPS}});
396}
397
398
399##############################################################################
400#
401# handler - takes a packet and calls the correct handler.
402#
403##############################################################################
404sub handler
405{
406    my $self = shift;
407    my $sid = shift;
408    my $packet = shift;
409
410    $self->handleIQ($packet) if ($packet->GetTag() eq "iq");
411    $self->handlePresence($packet) if ($packet->GetTag() eq "presence");
412}
413
414
415##############################################################################
416#
417# handleIQ - takes an iq packet that contains roster, parses it, and puts
418#            the roster into the Roster DB.
419#
420##############################################################################
421sub handleIQ
422{
423    my $self = shift;
424    my $iq = shift;
425
426    print "handleIQ: iq(",$iq->GetXML(),")\n";
427
428    my $type = $iq->GetType();
429    return unless (($type eq "set") || ($type eq "result"));
430
431    my %newroster = $self->{CONNECTION}->RosterParse($iq);
432
433    $self->handleRoster(\%newroster);
434}
435
436
437sub handleRoster
438{
439    my $self = shift;
440    my $roster = shift;
441
442    foreach my $jid (keys(%{$roster}))
443    {
444        $self->remove($jid);
445
446        if ($roster->{$jid}->{subscription} ne "remove")
447        {
448            $self->add($jid, %{$roster->{$jid}});
449        }
450    }
451}
452
453
454##############################################################################
455#
456# handlePresence - takes a presence packet and groks the presence.
457#
458##############################################################################
459sub handlePresence
460{
461    my $self = shift;
462    my $presence = shift;
463
464    print "handlePresence: presence(",$presence->GetXML(),")\n";
465
466    my $type = $presence->GetType();
467    $type = "" unless defined($type);
468    return unless (($type eq "") ||
469                   ($type eq "available") ||
470                   ($type eq "unavailable"));
471
472    my $jid = $presence->GetFrom("jid");
473
474    my $resource = $jid->GetResource();
475    $resource = " " unless ($resource ne "");
476   
477    $jid = $jid->GetJID();
478    $jid = "" unless defined($jid);
479
480    return unless $self->exists($jid);
481    #XXX if it doesn't exist... is it us?
482    #XXX is this a presence based roster?
483
484    $self->{CONNECTION}->{DEBUG}->Log3("Roster::PresenceDBParse: fromJID(",$presence->GetFrom(),") resource($resource) type($type)");
485    $self->{CONNECTION}->{DEBUG}->Log4("Roster::PresenceDBParse: xml(",$presence->GetXML(),")");
486
487    $self->removeResource($jid,$resource);
488
489    if (($type eq "") || ($type eq "available"))
490    {
491        my %item;
492       
493        $item{priority} = $presence->GetPriority();
494        $item{priority} = 0 unless defined($item{priority});
495
496        $item{show} = $presence->GetShow();
497        $item{show} = "" unless defined($item{show});
498
499        $item{status} = $presence->GetStatus();
500        $item{status} = "" unless defined($item{status});
501
502        $self->addResource($jid,$resource,%item);
503    }
504}
505
506
507##############################################################################
508#
509# jids - returns a list of all of the JIDs in your roster.
510#
511##############################################################################
512sub jids
513{
514    my $self = shift;
515    my $type = shift;
516    my $group = shift;
517
518    $type = "all" unless defined($type);
519
520    my @jids;
521
522    if (($type eq "all") || ($type eq "nogroup"))
523    {
524        return () unless exists($self->{JIDS});
525        foreach my $jid (keys(%{$self->{JIDS}}))
526        {
527            next if (($type eq "nogroup") &&
528                     exists($self->{JIDS}->{$jid}->{groups}) &&
529                     ($#{$self->{JIDS}->{$jid}->{groups}} > -1));
530
531            push(@jids,new Net::XMPP::JID($jid));
532        }
533    }
534   
535    if ($type eq "group")
536    {
537        return () unless exists($self->{GROUPS});
538        if (defined($group) && $self->groupExists($group))
539        {
540            foreach my $jid (keys(%{$self->{GROUPS}->{$group}}))
541            {
542                push(@jids,new Net::XMPP::JID($jid));
543            }
544        }
545    }
546
547    return @jids;
548}
549
550
551###############################################################################
552#
553# online - returns if the jid is online or not.
554#
555###############################################################################
556sub online
557{
558    my $self = shift;
559    my $jid = shift;
560
561    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
562
563    return unless $self->exists($jid);
564
565    my @resources = $self->resources($jid);
566
567    return ($#resources > -1);
568}
569
570
571##############################################################################
572#
573# priority - return the highest priority for the jid, or for the specified
574#            resource.
575#
576##############################################################################
577sub priority
578{
579    my $self = shift;
580    my $jid = shift;
581    my $resource = shift;
582
583    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
584   
585    if (defined($resource))
586    {
587        return unless $self->resourceExists($jid,$resource);
588        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{priority});
589        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority};
590    }
591   
592    return unless exists($self->{JIDS}->{$jid}->{priorities});
593    my @priorities = sort{ $b <=> $a } keys(%{$self->{JIDS}->{$jid}->{priorities}});
594    return $priorities[0];
595}
596
597
598##############################################################################
599#
600# query - allows you to get one of the pieces of info from the Roster DB.
601#
602##############################################################################
603sub query
604{
605    my $self = shift;
606    my $jid = shift;
607    my $key = shift;
608
609    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
610   
611    return unless $self->exists($jid);
612    if (defined($key))
613    {
614        return unless exists($self->{JIDS}->{$jid}->{$key});
615        return $self->{JIDS}->{$jid}->{$key};
616    }
617    return %{$self->{JIDS}->{$jid}};
618}
619
620
621##############################################################################
622#
623# remove - removes the JID from the Roster DB.
624#
625##############################################################################
626sub remove
627{
628    my $self = shift;
629    my $jid = shift;
630
631    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
632
633    if ($self->exists($jid))
634    {
635        $self->{CONNECTION}->{DEBUG}->Log3("Roster::remove: deleting $jid from the DB");
636       
637        if (defined($self->query($jid,"groups")))
638        {
639            foreach my $group (@{$self->query($jid,"groups")})
640            {
641                delete($self->{GROUPS}->{$group}->{$jid});
642                delete($self->{GROUPS}->{$group})
643                    if (scalar(keys(%{$self->{GROUPS}->{$group}})) == 0);
644                delete($self->{GROUPS})
645                    if (scalar(keys(%{$self->{GROUPS}})) == 0);
646            }
647        }
648   
649        delete($self->{JIDS}->{$jid});
650        delete($self->{JIDS}) if (scalar(keys(%{$self->{JIDS}})) == 0);
651    }
652}
653
654
655##############################################################################
656#
657# removeResource - removes the resource from the JID from the Roster DB.
658#
659##############################################################################
660sub removeResource
661{
662    my $self = shift;
663    my $jid = shift;
664    my $resource = shift;
665
666    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
667
668    if ($self->resourceExists($jid,$resource))
669    {
670        $self->{CONNECTION}->{DEBUG}->Log3("Roster::removeResource: remove $jid/$resource from the DB");
671
672        my $oldPriority = $self->priority($jid,$resource);
673        $oldPriority = "" unless defined($oldPriority);
674
675        if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}))
676        {
677            my $loc = 0;
678            foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}})
679            {
680                $loc = $index
681                    if ($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}->[$index]->{resource} eq $resource);
682            }
683           
684            splice(@{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}},$loc,1);
685
686            delete($self->{JIDS}->{$jid}->{priorities}->{$oldPriority})
687                if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}) &&
688                    ($#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}} == -1));
689        }
690
691        delete($self->{JIDS}->{$jid}->{resources}->{$resource});
692
693    }
694}
695
696
697###############################################################################
698#
699# resource - retrieve the resource with the highest priority.
700#
701###############################################################################
702sub resource
703{
704    my $self = shift;
705    my $jid = shift;
706
707    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
708
709    return unless $self->exists($jid);
710
711    my $priority = $self->priority($jid);
712
713    return unless defined($priority);
714
715    return $self->{JIDS}->{$jid}->{priorities}->{$priority}->[0]->{resource};
716}
717
718
719##############################################################################
720#
721# resourceExists - check that the specified resource exists.
722#
723##############################################################################
724sub resourceExists
725{
726    my $self = shift;
727    my $jid = shift;
728    my $resource = shift;
729   
730    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
731
732    return unless $self->exists($jid);
733    return unless exists($self->{JIDS}->{$jid}->{resources});
734    return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource});
735}
736
737
738##############################################################################
739#
740# resourceQuery - allows you to get one of the pieces of info from the Roster
741#                 DB.
742#
743##############################################################################
744sub resourceQuery
745{
746    my $self = shift;
747    my $jid = shift;
748    my $resource = shift;
749    my $key = shift;
750
751    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
752   
753    return unless $self->resourceExists($jid,$resource);
754    if (defined($key))
755    {
756        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{$key});
757        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key};
758    }
759    return %{$self->{JIDS}->{$jid}->{resources}->{$resource};}
760}
761
762
763###############################################################################
764#
765# resources - returns a list of the resources from highest priority to lowest.
766#
767###############################################################################
768sub resources
769{
770    my $self = shift;
771    my $jid = shift;
772
773    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
774
775    return () unless $self->exists($jid);
776
777    my @resources;
778
779    foreach my $priority (sort {$b cmp $a} keys(%{$self->{JIDS}->{$jid}->{priorities}}))
780    {
781        foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
782        {
783            next if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq " ");
784            push(@resources,$self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource});
785        }
786    }
787    return @resources;
788}
789
790
791##############################################################################
792#
793# resourceStore - allows you to store anything on the item that you want to.
794#                 The only drawback is that when the item is removed, the data
795#                 is not kept.  You must restore it in the DB.
796#
797##############################################################################
798sub resourceStore
799{
800    my $self = shift;
801    my $jid = shift;
802    my $resource = shift;
803    my $key = shift;
804    my $value = shift;
805
806    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
807
808    return unless defined($key);
809    return unless defined($value);
810    return unless $self->resourceExists($jid,$resource);
811
812    $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key} = $value;
813}
814
815
816##############################################################################
817#
818# store - allows you to store anything on the item that you want to.  The
819#         only drawback is that when the item is removed, the data is not
820#         kept.  You must restore it in the DB.
821#
822##############################################################################
823sub store
824{
825    my $self = shift;
826    my $jid = shift;
827    my $key = shift;
828    my $value = shift;
829
830    $jid = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
831
832    return unless defined($key);
833    return unless defined($value);
834    return unless $self->exists($jid);
835
836    $self->{JIDS}->{$jid}->{$key} = $value;
837}
838
839
8401;
841
Note: See TracBrowser for help on using the repository browser.