File Coverage

blib/lib/Protocol/XMPP/Handler.pm
Criterion Covered Total %
statement 12 61 19.6
branch 0 16 0.0
condition 0 7 0.0
subroutine 4 12 33.3
pod 3 8 37.5
total 19 104 18.2


line stmt bran cond sub pod time code
1             package Protocol::XMPP::Handler;
2              
3 3     3   315631 use strict;
  3         8  
  3         152  
4 3     3   21 use warnings;
  3         14  
  3         310  
5 3     3   25 use parent qw(XML::SAX::Base);
  3         11  
  3         26  
6              
7             our $VERSION = '0.007'; ## VERSION
8              
9             =head1 NAME
10              
11             =head1 SYNOPSIS
12              
13             =head1 DESCRIPTION
14              
15             =head1 METHODS
16              
17             =cut
18              
19 3     3   58430 use Module::Load ();
  3         4029  
  3         1735  
20              
21             # mainly used for debugging / tracing which modules were loaded
22             my %ClassLoaded;
23              
24             sub class_from_element {
25 0     0 0   my $self = shift;
26 0           my $name = shift;
27             # Allow entries on the stack to have the first
28             # go at handling the element.
29 0 0 0       if($self->{stack} && $self->{stack}[-1]) {
30 0           my $local = $self->{stack}[-1]->class_from_element($name);
31 0 0         return $local if $local;
32             }
33             my $class = {
34             'unknown' => '',
35              
36             'stream:features' => 'Protocol::XMPP::Element::Features',
37             'iq' => 'Protocol::XMPP::Element::IQ',
38             'feature' => 'Protocol::XMPP::Element::Feature',
39             'bind' => 'Protocol::XMPP::Element::Bind',
40             'session' => 'Protocol::XMPP::Element::Session',
41             'mechanism' => 'Protocol::XMPP::Element::Mechanism',
42             'mechanisms' => 'Protocol::XMPP::Element::Mechanisms',
43             'auth' => 'Protocol::XMPP::Element::Auth',
44             'challenge' => 'Protocol::XMPP::Element::Challenge',
45             'response' => 'Protocol::XMPP::Element::Response',
46             'success' => 'Protocol::XMPP::Element::Success',
47             'register' => 'Protocol::XMPP::Element::Register',
48             'starttls' => 'Protocol::XMPP::Element::StartTLS',
49             'proceed' => 'Protocol::XMPP::Element::Proceed',
50             'jid' => 'Protocol::XMPP::Element::JID',
51             'presence' => 'Protocol::XMPP::Element::Presence',
52              
53             'html' => 'Protocol::XMPP::Element::HTML',
54              
55             'message' => 'Protocol::XMPP::Element::Message',
56             'body' => 'Protocol::XMPP::Element::Body',
57             'subject' => 'Protocol::XMPP::Element::Subject',
58             'active' => 'Protocol::XMPP::Element::Active',
59             'nick' => 'Protocol::XMPP::Element::Nick',
60             'stream:stream' => 'Protocol::XMPP::Element::Stream',
61 0 0 0       }->{$name || 'unknown'} or return '';
62 0 0         unless($ClassLoaded{$class}) {
63 0           Module::Load::load($class);
64 0           ++$ClassLoaded{$class};
65             }
66 0           return $class;
67             }
68              
69             sub new {
70 0     0 0   my $class = shift;
71 0           my %args = @_;
72 0           my $self = $class->SUPER::new(@_);
73 0           $self->{stream} = delete $args{stream};
74 0           return $self;
75             }
76              
77 0     0 0   sub stream { shift->{stream} }
78              
79             sub debug {
80 0     0 0   my $self = shift;
81 0           $self->stream->debug(@_);
82             }
83              
84             sub parent {
85 0     0 0   my $self = shift;
86 0   0       my ($parent) = grep { defined } reverse @{$self->{stack} ||= []};
  0            
  0            
87 0           return $parent;
88             }
89              
90             =head2 start_element
91              
92             =cut
93              
94             sub start_element {
95 0     0 1   my $self = shift;
96 0           my $element = shift;
97              
98             # Find an appropriate class for this element
99 0           my $v = $element->{Name};
100 0           my $class = $self->class_from_element($v);
101              
102 0 0         if($class) {
103             my $obj = $class->new(
104             element => $element,
105             stream => $self->{stream},
106 0           parent => $self->parent
107             );
108 0           push @{$self->{stack}}, $obj;
  0            
109             } else {
110 0           $self->debug("Not sure about the element for $v");
111 0           push @{$self->{stack}}, undef;
  0            
112             }
113 0           return $self->SUPER::start_element($element);
114             }
115              
116             =head2 end_element
117              
118             =cut
119              
120             sub end_element {
121 0     0 1   my $self = shift;
122 0           my $data = shift;
123             # warn "=> Element [" . $data->{Name} . "] ends";
124 0           my $obj = pop @{$self->{stack}};
  0            
125 0 0         if($obj) {
126 0           $obj->end_element($data);
127             }
128 0           return $self->SUPER::end_element($data);
129             }
130              
131             =head2 characters
132              
133             =cut
134              
135             sub characters {
136 0     0 1   my $self = shift;
137 0           my $data = shift;
138 0 0         if(@{$self->{stack}}) {
  0            
139 0           my $obj = $self->{stack}[-1];
140 0 0         $obj->characters($data->{Data}) if $obj;
141             }
142 0           return $self->SUPER::characters($data);
143             }
144              
145             1;
146              
147             __END__