home *** CD-ROM | disk | FTP | other *** search
/ Netrunner 2004 October / NETRUNNER0410.ISO / regular / ActivePerl-5.8.4.810-MSWin32-x86.msi / _5bad9853769dfd3e58f0dddea41a1bbe < prev    next >
Encoding:
Text File  |  2004-06-01  |  8.0 KB  |  295 lines

  1. # ======================================================================
  2. #
  3. # Copyright (C) 2000-2001 Paul Kulchenko (paulclinger@yahoo.com)
  4. # SOAP::Lite is free software; you can redistribute it
  5. # and/or modify it under the same terms as Perl itself.
  6. #
  7. # $Id: JABBER.pm,v 1.3 2001/08/11 19:09:57 paulk Exp $
  8. #
  9. # ======================================================================
  10.  
  11. package SOAP::Transport::JABBER;
  12.  
  13. use strict;
  14. use vars qw($VERSION);
  15. $VERSION = sprintf("%d.%s", map {s/_//g; $_} q$Name: release-0_55-public $ =~ /-(\d+)_([\d_]+)/);
  16.  
  17. use Net::Jabber 1.0021 qw(Client); 
  18. use URI::Escape; 
  19. use URI;
  20. use SOAP::Lite;
  21.  
  22. my $NAMESPACE = "http://namespaces.soaplite.com/transport/jabber";
  23.  
  24. { local $^W; 
  25.   # fix problem with printData in 1.0021
  26.   *Net::Jabber::printData = sub {'nothing'} if Net::Jabber->VERSION == 1.0021;
  27.  
  28.   # fix problem with Unicode encoding in EscapeXML. Jabber ALWAYS convert latin to utf8
  29.   *Net::Jabber::EscapeXML = *Net::Jabber::EscapeXML = # that's Jabber 1.0021
  30.   *XML::Stream::EscapeXML = *XML::Stream::EscapeXML = # that's Jabber 1.0022
  31.     \&SOAP::Utils::encode_data; 
  32.  
  33.   # There is also an error in XML::Stream::UnescapeXML 1.12, but
  34.   # we can't do anything there, except hack it also :(
  35. }
  36.  
  37. # ======================================================================
  38.  
  39. package URI::jabber; # ok, lets do 'jabber://' scheme
  40. require URI::_server; require URI::_userpass; 
  41. @URI::jabber::ISA=qw(URI::_server URI::_userpass);
  42.  
  43.   # jabber://soaplite_client:soapliteclient@jabber.org:5222/soaplite_server@jabber.org/Home
  44.   # ^^^^^^   ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
  45.  
  46. # ======================================================================
  47.  
  48. package SOAP::Transport::JABBER::Query;
  49.  
  50. sub new {
  51.   my $proto = shift;
  52.   bless {} => ref($proto) || $proto;
  53. }
  54.  
  55. sub SetPayload {
  56.   shift; Net::Jabber::SetXMLData("single",shift->{QUERY},"payload",shift,{});
  57. }
  58.  
  59. sub GetPayload {
  60.   shift; Net::Jabber::GetXMLData("value",shift->{QUERY},"payload","");
  61. }
  62.  
  63. # ======================================================================
  64.  
  65. package SOAP::Transport::JABBER::Client;
  66.  
  67. use vars qw(@ISA);
  68. @ISA = qw(SOAP::Client Net::Jabber::Client);
  69.  
  70. sub DESTROY { SOAP::Trace::objects('()') }
  71.  
  72. sub new { 
  73.   my $self = shift;
  74.  
  75.   unless (ref $self) {
  76.     my $class = ref($self) || $self;
  77.     my(@params, @methods);
  78.     while (@_) { $class->can($_[0]) ? push(@methods, shift() => shift) : push(@params, shift) }
  79.     $self = $class->SUPER::new(@params);
  80.     while (@methods) { my($method, $params) = splice(@methods,0,2);
  81.       $self->$method(ref $params eq 'ARRAY' ? @$params : $params) 
  82.     }
  83.     SOAP::Trace::objects('()');
  84.   }
  85.   return $self;
  86. }
  87.  
  88. sub endpoint {
  89.   my $self = shift;
  90.  
  91.   return $self->SUPER::endpoint unless @_;
  92.  
  93.   my $endpoint = shift;
  94.  
  95.   # nothing to do if new endpoint is the same as current one
  96.   return $self if $self->SUPER::endpoint && $self->SUPER::endpoint eq $endpoint;
  97.  
  98.   my $uri = URI->new($endpoint);
  99.   my($undef, $to, $resource) = split m!/!, $uri->path, 3;
  100.   $self->Connect(
  101.     hostname => $uri->host, 
  102.     port => $uri->port,
  103.   ) or Carp::croak "Can't connect to @{[$uri->host_port]}: $!";
  104.  
  105.   my @result = $self->AuthSend(
  106.     username => $uri->user, 
  107.     password => $uri->password,
  108.     resource => 'soapliteClient',
  109.   );
  110.   $result[0] eq "ok" or Carp::croak "Can't authenticate to @{[$uri->host_port]}: @result";
  111.  
  112.   $self->AddDelegate(
  113.     namespace  => $NAMESPACE,
  114.     parent     => 'Net::Jabber::Query',
  115.     parenttype => 'query',
  116.     delegate   => 'SOAP::Transport::JABBER::Query',
  117.   );
  118.  
  119.   # Get roster and announce presence
  120.   $self->RosterGet();
  121.   $self->PresenceSend();
  122.  
  123.   $self->SUPER::endpoint($endpoint);
  124. }
  125.  
  126. sub send_receive {
  127.   my($self, %parameters) = @_;
  128.   my($envelope, $endpoint, $encoding) = 
  129.     @parameters{qw(envelope endpoint encoding)};
  130.  
  131.   $self->endpoint($endpoint ||= $self->endpoint);
  132.  
  133.   my($undef, $to, $resource) = split m!/!, URI->new($endpoint)->path, 3;
  134.  
  135.   # Create a Jabber info/query message
  136.   my $iq = new Net::Jabber::IQ();
  137.   $iq->SetIQ(
  138.     type => 'set',
  139.     to   => join '/', $to => $resource || 'soapliteServer',
  140.   );
  141.   my $query = $iq->NewQuery($NAMESPACE);
  142.   $query->SetPayload($envelope);
  143.  
  144.   SOAP::Trace::debug($envelope);
  145.  
  146.   my $iq_rcvd = $self->SendAndReceiveWithID($iq);
  147.   my($query_rcvd) = $iq_rcvd->GetQuery($NAMESPACE) if $iq_rcvd; # expect only one
  148.   my $msg = $query_rcvd->GetPayload() if $query_rcvd;
  149.  
  150.   SOAP::Trace::debug($msg);
  151.  
  152.   my $code = $self->GetErrorCode();
  153.  
  154.   $self->code($code);
  155.   $self->message($code);
  156.   $self->is_success(!defined $code || $code eq '');
  157.   $self->status($code);
  158.  
  159.   return $msg;
  160. }
  161.  
  162. # ======================================================================
  163.  
  164. package SOAP::Transport::JABBER::Server;
  165.  
  166. use Carp ();
  167. use vars qw(@ISA $AUTOLOAD);
  168. @ISA = qw(SOAP::Server);
  169.  
  170. sub new {
  171.   my $self = shift;
  172.     
  173.   unless (ref $self) {
  174.     my $class = ref($self) || $self;
  175.     my $uri = URI->new(shift);
  176.     $self = $class->SUPER::new(@_);
  177.  
  178.     $self->{_jabberserver} = Net::Jabber::Client->new;
  179.     $self->{_jabberserver}->Connect(
  180.       hostname      => $uri->host,
  181.       port          => $uri->port,
  182.     ) or Carp::croak "Can't connect to @{[$uri->host_port]}: $!";
  183.  
  184.     my($undef, $resource) = split m!/!, $uri->path, 2;
  185.     my @result = $self->AuthSend(
  186.       username => $uri->user, 
  187.       password => $uri->password,
  188.       resource => $resource || 'soapliteServer',
  189.     );
  190.     $result[0] eq "ok" or Carp::croak "Can't authenticate to @{[$uri->host_port]}: @result";
  191.  
  192.     $self->{_jabberserver}->SetCallBacks(
  193.       iq => sub {
  194.         shift;
  195.         my $iq = new Net::Jabber::IQ(@_);
  196.  
  197.         my($query) = $iq->GetQuery($NAMESPACE); # expect only one
  198.         my $request = $query->GetPayload();
  199.  
  200.         SOAP::Trace::debug($request);
  201.  
  202.         # Set up response
  203.         my $reply = $iq->Reply;
  204.         my $x = $reply->NewQuery($NAMESPACE);
  205.  
  206.         my $response = $self->SUPER::handle($request);
  207.         $x->SetPayload($response);
  208.  
  209.         # Send response
  210.         $self->{_jabberserver}->Send($reply);
  211.       }
  212.     );
  213.  
  214.     $self->AddDelegate(
  215.       namespace  => $NAMESPACE,
  216.       parent     => 'Net::Jabber::Query',
  217.       parenttype => 'query',
  218.       delegate   => 'SOAP::Transport::JABBER::Query',
  219.     );
  220.   
  221.     $self->RosterGet();
  222.     $self->PresenceSend();
  223.   }
  224.   return $self;
  225. }
  226.  
  227. sub AUTOLOAD {
  228.   my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::') + 2);
  229.   return if $method eq 'DESTROY';
  230.  
  231.   no strict 'refs';
  232.   *$AUTOLOAD = sub { shift->{_jabberserver}->$method(@_) };
  233.   goto &$AUTOLOAD;
  234. }
  235.  
  236. sub handle {
  237.   shift->Process();
  238. }
  239.  
  240. # ======================================================================
  241.  
  242. 1;
  243.  
  244. __END__
  245.  
  246. =head1 NAME
  247.  
  248. SOAP::Transport::JABBER - Server/Client side JABBER support for SOAP::Lite
  249.  
  250. =head1 SYNOPSIS
  251.  
  252. =over 4
  253.  
  254. =item Client
  255.  
  256.   use SOAP::Lite 
  257.     uri => 'http://my.own.site.com/My/Examples',
  258.     proxy => 'jabber://username:password@jabber.org:5222/soaplite_server@jabber.org/',
  259.     #         proto    username passwd   server     port destination                resource (optional)
  260.   ;
  261.  
  262.   print getStateName(1);
  263.  
  264. =item Server
  265.  
  266.   use SOAP::Transport::JABBER;
  267.  
  268.   my $server = SOAP::Transport::JABBER::Server
  269.     -> new('jabber://username:password@jabber.org:5222')
  270.     # specify list of objects-by-reference here 
  271.     -> objects_by_reference(qw(My::PersistentIterator My::SessionIterator My::Chat))
  272.     # specify path to My/Examples.pm here
  273.     -> dispatch_to('/Your/Path/To/Deployed/Modules', 'Module::Name', 'Module::method')
  274.   ;
  275.  
  276.   print "Contact to SOAP server\n";
  277.   do { $server->handle } while sleep 10;
  278.  
  279. =back
  280.  
  281. =head1 DESCRIPTION
  282.  
  283. =head1 COPYRIGHT
  284.  
  285. Copyright (C) 2000-2001 Paul Kulchenko. All rights reserved.
  286.  
  287. This library is free software; you can redistribute it and/or modify
  288. it under the same terms as Perl itself.
  289.  
  290. =head1 AUTHOR
  291.  
  292. Paul Kulchenko (paulclinger@yahoo.com)
  293.  
  294. =cut
  295.