File Coverage

blib/lib/RDF/Sesame/Response.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package RDF::Sesame::Response;
2              
3 8     8   48 use strict;
  8         13  
  8         289  
4 8     8   40 use warnings;
  8         13  
  8         218  
5 8     8   8938 use XML::Simple;
  0            
  0            
6              
7             our $VERSION = '0.17';
8              
9             # simple accessors
10             sub errstr { return $_[0]->{error} }
11             sub http_response { return $_[0]->{http} }
12             sub parsed_xml { return $_[0]->{parsed} }
13             sub success { return $_[0]->{success} }
14             sub xml { return $_[0]->{xml} }
15              
16             sub content {
17             my ($self) = @_;
18             return $self->http_response()->content();
19             }
20              
21             sub is_xml {
22             my ($self) = @_;
23             my $content_type = $self->http_response()->header('Content-type');
24             return $content_type =~ m{ text/xml }xms;
25             }
26              
27             sub is_binary_results {
28             my ($self) = @_;
29             my $content_type = $self->http_response()->header('Content-type');
30             return $content_type =~ m{ application/x-binary-rdf-results-table }xms;
31             }
32              
33             #
34             # Creates a new RDF::Sesame::Response object.
35             #
36             # The parameter $response is an HTTP::Response object
37             #
38             sub new {
39             my ($class, $r) = @_;
40              
41             my $self = bless {
42             http => $r, # our original HTTP::Response object
43             success => 0, # was the command sucessful?
44             xml => '', # the XML from the server
45             error => '', # the error message from the server
46             parsed => {}, # a hashref representing the parsed XML
47             }, $class;
48              
49             # return an empty object if we got no HTTP::Response
50             return $self unless $r;
51              
52             if ( !$r->is_success() ) {
53             $self->{error} = $r->message();
54             return $self;
55             }
56              
57             $self->{success} = 1;
58             return $self if !$self->is_xml();
59              
60             # because the XML for tuples prevents XML::Simple
61             # from retaining the attribute order, we do a transform
62             # to improve the XML.
63             # See the documentation for _fix_tuple()
64             my $xml = $self->{xml} = $r->content();
65             $xml =~ s#(.*?)#_fix_tuple($1)#siegx;
66              
67             # TODO call a custom XML::SAX parser instead
68             $self->{parsed} = XMLin(
69             $xml,
70             ForceArray => [
71             qw(repository status notification
72             columnName tuple attribute
73             error )
74             ],
75             KeyAttr => [ ],
76             );
77              
78             # examine the XML for error responses
79             if( exists $self->{parsed}{error} ) {
80             $self->{success} = 0;
81             $self->{error} = @{$self->{parsed}{error}}[0]->{msg};
82             }
83              
84             return $self;
85             }
86              
87             # The XML returned by Sesame after evaluating a table query
88             # contains the attributes of each tuple in the same order as
89             # the attribute (column) names. This order is not preserved by XML::Simple
90             # so we need to transform the provided-XML into a more useful form.
91             # This could be done with XSLT but that's overkill, so
92             # we jut use regular expressions.
93             #
94             # An example transform would take XML like this
95             #
96             #
97             # node1
98             # Hello
99             # http://example.com
100             # World!
101             #
102             #
103             # and transform it into XML like this
104             #
105             #
106             # node1
107             # Hello
108             # http://example.com
109             # World!
110             #
111             sub _fix_tuple {
112             my $content = shift;
113              
114             $content =~ s#
115             <\s*(bNode|literal|uri)(.*?)>(.*?)
116             #$3#sgix;
117              
118             $content =~ s#
119             <\s*(null)(.*?)\s*/\s*>
120             ##sgix;
121              
122             return "$content";
123             }
124              
125             1;
126              
127             __END__