##############################################################################
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
#
# Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
#
##############################################################################
package Net::XMPP::IQ;
=head1 NAME
Net::XMPP::IQ - XMPP Info/Query Module
=head1 SYNOPSIS
Net::XMPP::IQ is a companion to the Net::XMPP module. It
provides the user a simple interface to set and retrieve all
parts of an XMPP IQ.
=head1 DESCRIPTION
Net::XMPP::IQ differs from the other Net::XMPP::* modules in that
the XMLNS of the query is split out into a submodule under
IQ. For specifics on each module please view the documentation
for the Net::XMPP::Namespaces module.
A Net::XMPP::IQ object is passed to the callback function for the
message. Also, the first argument to the callback functions is the
session ID from XML::Stream. There are some cases where you might
want this information, like if you created a Client that connects to
two servers at once, or for writing a mini server.
use Net::XMPP;
sub iq {
my ($sid,$IQ) = @_;
.
.
my $reply = $IQ->Reply();
my $replyQuery->GetQuery();
.
}
You now have access to all of the retrieval functions available.
To create a new iq to send to the server:
use Net::XMPP;
$IQ = Net::XMPP::IQ->new();
$IQType = $IQ->NewChild( type );
$IQType->SetXXXXX("yyyyy");
Now you can call the creation functions for the IQ, and for the
<query/> on the new query object itself. See below for the <iq/>
functions, and in each query module for those functions.
=head1 METHODS
=head2 General functions
Reply(%args) - Creates a return <iq/> with the to and from
filled in correctly, and a query object already
added in. The %args that you pass are passed
to SetIQ() and will overwrite the IQ settings
that Reply sets.
=head2 Retrieval functions
GetTo() - returns either a string with the JID, or a
GetTo("jid") Net::XMPP::JID object for the person who is
going to receive the <iq/>. To get the JID
object set the string to "jid", otherwise leave
blank for the text string.
$to = $IQ->GetTo();
$toJID = $IQ->GetTo("jid");
GetFrom() - returns either a string with the JID, or a
GetFrom("jid") Net::XMPP::JID object for the person who
sent the <iq/>. To get the JID object set
the string to "jid", otherwise leave blank for the
text string.
$from = $IQ->GetFrom();
$fromJID = $IQ->GetFrom("jid");
GetType() - returns a string with the type <iq/> this is.
$type = $IQ->GetType();
GetID() - returns an integer with the id of the <iq/>.
$id = $IQ->GetID();
GetError() - returns a string with the text description of the error.
$error = $IQ->GetError();
GetErrorCode() - returns a string with the code of error.
$errorCode = $IQ->GetErrorCode();
GetQuery() - returns a Net::XMPP::Stanza object that contains the data
in the query of the <iq/>. Basically, it returns the
first child in the <iq/>.
$query = $IQ->GetQuery();
GetQueryXMLNS() - returns a string with the namespace of the query
for this <iq/>, if one exists.
$xmlns = $IQ->GetQueryXMLNS();
=head2 Creation functions
SetIQ(to=>string|JID, - set multiple fields in the <iq/> at one
from=>string|JID, time. This is a cumulative and over
id=>string, writing action. If you set the "to"
type=>string, attribute twice, the second setting is
errorcode=>string, what is used. If you set the status, and
error=>string) then set the priority then both will be in
the <iq/> tag. For valid settings read the
specific Set functions below.
$IQ->SetIQ(type=>"get",
to=>"bob\@jabber.org");
$IQ->SetIQ(to=>"bob\@jabber.org",
errorcode=>403,
error=>"Permission Denied");
SetTo(string) - sets the to attribute. You can either pass a string
SetTo(JID) or a JID object. They must be a valid Jabber
Identifiers or the server will return an error message.
(ie. bob@jabber.org, etc...)
$IQ->SetTo("bob\@jabber.org");
SetFrom(string) - sets the from attribute. You can either pass a
SetFrom(JID) string or a JID object. They must be a valid JIDs
or the server will return an error message.
(ie. bob@jabber.org, etc...)
$IQ->SetFrom("me\@jabber.org");
SetType(string) - sets the type attribute. Valid settings are:
get request information
set set information
result results of a get
error there was an error
$IQ->SetType("set");
SetErrorCode(string) - sets the error code of the <iq/>.
$IQ->SetErrorCode(403);
SetError(string) - sets the error string of the <iq/>.
$IQ->SetError("Permission Denied");
NewChild(string) - creates a new Net::XMPP::Stanza object with the
namespace in the string. In order for this
function to work with a custom namespace, you
must define and register that namespace with the
IQ module. For more information please read the
documentation for Net::XMPP::Stanza.
$queryObj = $IQ->NewChild("jabber:iq:auth");
$queryObj = $IQ->NewChild("jabber:iq:roster");
Reply(hash) - creates a new IQ object and populates the to/from
fields. If you specify a hash the same as with SetIQ
then those values will override the Reply values.
$iqReply = $IQ->Reply();
$iqReply = $IQ->Reply(type=>"result");
=head2 Removal functions
RemoveTo() - removes the to attribute from the <iq/>.
$IQ->RemoveTo();
RemoveFrom() - removes the from attribute from the <iq/>.
$IQ->RemoveFrom();
RemoveID() - removes the id attribute from the <iq/>.
$IQ->RemoveID();
RemoveType() - removes the type attribute from the <iq/>.
$IQ->RemoveType();
RemoveError() - removes the <error/> element from the <iq/>.
$IQ->RemoveError();
RemoveErrorCode() - removes the code attribute from the <error/>
element in the <iq/>.
$IQ->RemoveErrorCode();
=head2 Test functions
DefinedTo() - returns 1 if the to attribute is defined in the <iq/>,
0 otherwise.
$test = $IQ->DefinedTo();
DefinedFrom() - returns 1 if the from attribute is defined in the
<iq/>, 0 otherwise.
$test = $IQ->DefinedFrom();
DefinedID() - returns 1 if the id attribute is defined in the <iq/>,
0 otherwise.
$test = $IQ->DefinedID();
DefinedType() - returns 1 if the type attribute is defined in the
<iq/>, 0 otherwise.
$test = $IQ->DefinedType();
DefinedError() - returns 1 if <error/> is defined in the <iq/>,
0 otherwise.
$test = $IQ->DefinedError();
DefinedErrorCode() - returns 1 if the code attribute is defined in
<error/>, 0 otherwise.
$test = $IQ->DefinedErrorCode();
DefinedQuery() - returns 1 if there is at least one namespaced
child in the object.
=head1 AUTHOR
Originally authored by Ryan Eatmon.
Previously maintained by Eric Hacker.
Currently maintained by Darian Anthony Patrick.
=head1 COPYRIGHT
This module is free software, you can redistribute it and/or modify it
under the LGPL 2.1.
=cut
require 5.008;
use strict;
use warnings;
use Carp;
use vars qw( %FUNCTIONS );
use Net::XMPP::Stanza;
use base qw( Net::XMPP::Stanza );
sub new
{
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = { };
bless($self, $proto);
$self->{DEBUGHEADER} = "IQ";
$self->{TAG} = "iq";
$self->{FUNCS} = \%FUNCTIONS;
$self->_init(@_);
return $self;
}
sub _iq { my $self = shift; return Net::XMPP::IQ->new(); }
$FUNCTIONS{Error}->{path} = 'error/text()';
$FUNCTIONS{ErrorCode}->{path} = 'error/@code';
$FUNCTIONS{From}->{type} = 'jid';
$FUNCTIONS{From}->{path} = '@from';
$FUNCTIONS{ID}->{path} = '@id';
$FUNCTIONS{To}->{type} = 'jid';
$FUNCTIONS{To}->{path} = '@to';
$FUNCTIONS{Type}->{path} = '@type';
$FUNCTIONS{XMLNS}->{path} = '@xmlns';
$FUNCTIONS{IQ}->{type} = 'master';
$FUNCTIONS{Child}->{type} = 'child';
$FUNCTIONS{Child}->{path} = '*[@xmlns]';
$FUNCTIONS{Child}->{child} = { };
$FUNCTIONS{Query}->{type} = 'child';
$FUNCTIONS{Query}->{path} = '*[@xmlns][0]';
$FUNCTIONS{Query}->{child} = { child_index=>0 };
##############################################################################
#
# GetQueryXMLNS - returns the xmlns of the first child
#
##############################################################################
sub GetQueryXMLNS
{
my $self = shift;
return $self->{CHILDREN}->[0]->GetXMLNS() if ($#{$self->{CHILDREN}} > -1);
}
##############################################################################
#
# Reply - returns a Net::XMPP::IQ object with the proper fields
# already populated for you.
#
##############################################################################
sub Reply
{
my $self = shift;
my %args;
while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
my $reply = $self->_iq();
$reply->SetID($self->GetID()) if ($self->GetID() ne "");
$reply->SetType("result");
$reply->NewChild($self->GetQueryXMLNS());
$reply->SetIQ((($self->GetFrom() ne "") ?
(to=>$self->GetFrom()) :
()
),
(($self->GetTo() ne "") ?
(from=>$self->GetTo()) :
()
),
);
$reply->SetIQ(%args);
return $reply;
}
1;