File Coverage

blib/lib/WebSource/Envelope.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1             package WebSource::Envelope;
2              
3 2     2   25662 use strict;
  2         5  
  2         66  
4 2     2   12 use Carp;
  2         3  
  2         184  
5 2     2   7632 use URI;
  2         12920  
  2         55  
6 2     2   6102 use HTTP::Request::Common;
  2         47104  
  2         173  
7 2     2   960 use XML::LibXML::Common qw(:w3c);
  0            
  0            
8             use XML::LibXML;
9              
10             =head1 NAME
11              
12             WebSource::Envelope - Container for exchanged data
13              
14             =head1 DESCRIPTION
15              
16             A WebSource::Enveloppe is used to encapsulate the data
17             going from one module to another. This alows to attach
18             meta-information such as a document's base uri
19              
20             For the moment these types are known :
21              
22             =over 2
23              
24             =item - B
25              
26             data is an XML::LibXML Node
27              
28             =item - B
29              
30             data is a string
31              
32             =item - B
33              
34             data is a URI object
35              
36             =item - B
37              
38             data is an HTTP::Request object
39              
40             =back
41              
42             =head1 SYNOPSIS
43              
44             use WebSource::Envelope;
45             ...
46             my $env = WebSource::Envelope->new(
47             type => $type,
48             data => $data
49             ...
50             );
51             ...
52              
53              
54             =head1 METHODS
55              
56             =cut
57              
58             our %knowntypes = (
59             "object/dom-node" => 1,
60             "object/http-request" => 1,
61             "text/string" => 1,
62             "text/html" => 1,
63             "text/xml" => 1,
64             "object/uri" => 1,
65             "application/pdf" => 1,
66             "empty" => 1
67             );
68              
69             sub new {
70             my $class = shift;
71             my %params = @_;
72             my $self = bless \%params, $class;
73             $self->{type} or croak("No type given");
74             $knowntypes{$self->{type}} or carp("Type ",$self->{type}," is not known");
75             return $self;
76             }
77              
78             sub new_from_file {
79             my ($class,$filename) = @_;
80             my $parser = XML::LibXML->new();
81             my $doc = $parser->parse_file($filename);
82             my $envRoot = $doc->documentElement();
83             my %params;
84             foreach my $attr ($envRoot->attributes()) {
85             $params{$attr->nodeName} = $attr->nodeValue;
86             }
87             my $self = bless \%params, $class;
88             $self->{type} or croak("No type given");
89             $knowntypes{$self->{type}} or carp("Type ",$self->{type}," is not known");
90             if($self->{type} eq 'object/dom-node') {
91             my @content = $envRoot->findnodes('child::*');
92             if(@content) {
93             $self->{data} = $content[0];
94             } else {
95             croak("No content for dom-node");
96             }
97             } else {
98             $self->{data} = $envRoot->findvalue('text()');
99             }
100             return $self;
101             }
102              
103             sub type {
104             my $self = shift;
105             return $self->{type};
106             }
107              
108             sub data {
109             my $self = shift;
110             return $self->{data};
111             }
112              
113             sub dataString {
114             my $self = shift;
115             my $t = $self->type;
116             my $d = $self->data;
117             if($t eq "object/dom-node") {
118             $d->textContent;
119             } elsif($t =~ m{^object/} && $d->can("as_string")) {
120             $d->as_string;
121             } else {
122             $d;
123             }
124             }
125              
126             sub dataXML {
127             my $self = shift;
128             my %params = @_;
129             my $t = $self->type;
130             my $d = $self->data;
131             if($t eq "object/dom-node") {
132             if($params{wantdoc} && $d->nodeType ne "#document") {
133             my $doc = XML::LibXML::Document->createDocument( "1.0", "utf-8" );
134            
135             my $clone = $d->cloneNode(1);
136             $doc->setDocumentElement($clone);
137             $doc->toString(1);
138             } else {
139             $d->toString(1);
140             }
141             } elsif($t =~ m{^object/} && $d->can("as_string")) {
142             "" . $d->as_string . "";
143             } else {
144             "" . $d . "";
145             }
146             }
147              
148             sub dataAsURI {
149             my $self = shift;
150             my $t = $self->type;
151             if($t eq "object/uri") {
152             return $self->data;
153             }
154             if($t eq "object/http-request") {
155             return URI->new($self->data->uri)
156             }
157             if($self->{baseuri}) {
158             return URI->new_abs($self->dataString,$self->{baseuri});
159             } else {
160             return URI->new($self->dataString);
161             }
162             }
163            
164             sub dataAsHttpRequest {
165             my $self = shift;
166             my $t = $self->type;
167             # print "Got data of type $t\n";
168             if($t eq "object/http-request") {
169             return $self->data;
170             }
171             if($t eq "object/dom-node") {
172             my $n = $self->data;
173             if($n->nodeType == DOCUMENT_NODE) {
174             $n = $n->documentElement;
175             }
176             # print "Namespace URI : ", $n->namespaceURI,"\n";
177             # print "Local name : ", $n->localName,"\n";
178             if($n->namespaceURI eq "http://wwwsource.free.fr/ns/websource-types"
179             && $n->localName eq "http-request") {
180             my $pre = $n->prefix;
181             my $base = $n->getAttribute("base");
182             my $method = $n->getAttribute("method");
183             # print $n->toString(1),"\n";
184             # print "Base : $base\n";
185             # print "Method : $method\n";
186             my $url = URI->new($base);
187             my @query = map {
188             $_->getAttribute("name") => $_->getAttribute("value")
189             } $n->findnodes("${pre}:param");
190             my $htreq;
191             if ($method =~ m/GET/i) {
192             $url->query_form(\@query);
193             $htreq = HTTP::Request->new("GET",$url);
194             } else {
195             $htreq = POST $url, \@query;
196             }
197             } else {
198             return HTTP::Request->new("GET",$self->dataAsURI->as_string);
199             }
200             } else {
201             return HTTP::Request->new("GET",$self->dataAsURI->as_string);
202             }
203             }
204              
205             sub as_string {
206             my $self = shift;
207             return "[[" . join(" ", map {
208             my $str = "";
209             $str .= $self->{$_};
210             my $l = length($str);
211             $l > 70 and $str = substr($str,0,35) . " ... " . substr($str,$l-35,35);
212             $_ . " => " . $str
213             } keys(%$self)) . "]]";
214             }
215              
216             sub to_file {
217             my ($self,$filename) = @_;
218             my $parser = new XML::LibXML;
219             my $envDoc = $parser->parse_string('');
220             my $envRoot = $envDoc->documentElement();
221             foreach my $key (keys(%$self)) {
222             if($key ne 'data') {
223             my $value = $self->{$key};
224             $envRoot->setAttribute($key,$value);
225             }
226             }
227              
228             my $t = $self->type;
229             my $d = $self->data;
230             if($t eq "object/dom-node") {
231             if($d->nodeType == XML_DOCUMENT_NODE) {
232             $envRoot->appendChild($d->documentElement);
233             } else {
234             $envRoot->appendChild($d);
235             }
236             } else {
237             $envRoot->appendChild($envDoc->create($d));
238             }
239            
240            
241             open(my $fh,">",$filename);
242             print $fh $envDoc->toString;
243             close($fh);
244             }
245              
246             =head1 SEE ALSO
247              
248             WebSource
249              
250             =cut
251              
252             1;