File Coverage

blib/lib/Protocol/Yadis/Document.pm
Criterion Covered Total %
statement 16 19 84.2
branch n/a
condition n/a
subroutine 6 7 85.7
pod n/a
total 22 26 84.6


line stmt bran cond sub pod time code
1             package Protocol::Yadis::Document;
2              
3 4     4   41587 use strict;
  4         9  
  4         139  
4 4     4   21 use warnings;
  4         9  
  4         472  
5              
6 4     4   9675 use overload '""' => sub { shift->to_string }, fallback => 1;
  4     0   11246  
  4         41  
  0         0  
7              
8 4     4   3232 use Protocol::Yadis::Document::Service;
  4         11  
  4         120  
9 4     4   2711 use Protocol::Yadis::Document::Service::Element;
  4         13  
  4         102  
10              
11 4     4   9285 use XML::LibXML;
  0            
  0            
12              
13             sub new {
14             my $class = shift;
15             my %param = @_;
16              
17             my $self = {};
18             bless $self, $class;
19              
20             $self->{_services} ||= [];
21              
22             return $self;
23             }
24              
25             sub services {
26             my $self = shift;
27              
28             if (@_) {
29             $self->{_services} = [];
30              
31             return $self;
32             }
33             else {
34             my @priority =
35             grep { defined $_->attr('priority') } @{$self->{_services}};
36             my @other =
37             grep { not defined $_->attr('priority') } @{$self->{_services}};
38              
39             my @sorted =
40             sort { $a->attr('priority') cmp $b->attr('priority') } @priority;
41             push @sorted, @other;
42              
43             return [@sorted];
44             }
45              
46             return $self->{_services};
47             }
48              
49             sub parse {
50             my $class = shift;
51             my $document = shift;
52              
53             my $self = $class->new;
54              
55             return unless $document;
56              
57             my $parser = XML::LibXML->new;
58             my $doc;
59             eval {$doc = $parser->parse_string($document); };
60             return if $@;
61              
62             # Get XRDS
63             my $xrds = shift @{$doc->getElementsByTagName('xrds:XRDS')};
64             $xrds = shift @{$doc->getElementsByTagName('XRDS')} unless $xrds;
65             return unless $xrds;
66              
67             # Get /last/ XRD
68             my @xrd = $xrds->getElementsByTagName('XRD');
69             my $xrd = $xrd[-1];
70             return unless $xrd;
71              
72             my $services = [];
73             my @services = $xrd->getElementsByTagName('Service');
74             foreach my $service (@services) {
75             my $s =
76             Protocol::Yadis::Document::Service->new(attrs =>
77             [map { $_->getName => $_->getValue } $service->attributes]);
78              
79             my $elements = [];
80             my @nodes = $service->childNodes;
81             foreach my $node (@nodes) {
82             next unless $node->isa('XML::LibXML::Element');
83              
84             my @attrs = $node->attributes;
85             my $content = $node->textContent;
86             $content =~ s/^\s*//s;
87             $content =~ s/\s*$//s;
88              
89             my $element = Protocol::Yadis::Document::Service::Element->new(
90             name => $node->getName,
91             content => $content,
92             attrs => [map { $_->getName => $_->getValue } @attrs]
93             );
94              
95             push @$elements, $element;
96             }
97              
98             $s->elements($elements);
99              
100             next unless $s->Type;
101              
102             push @{$self->{_services}}, $s;
103             }
104              
105             return $self;
106             }
107              
108             sub to_string {
109             my $self = shift;
110              
111             my $string = '';
112              
113             $string .= '' . "\n";
114              
115             $string .= '
116             $string .= ' xmlns:openid="http://openid.net/xmlns/1.0">' . "\n";
117              
118             $string .= " \n";
119              
120             foreach my $service (@{$self->services}) {
121             $string .= $service->to_string;
122             }
123              
124             $string .= " \n";
125             $string .= "\n";
126              
127             return $string;
128             }
129              
130             1;
131             __END__