File Coverage

blib/lib/Catmandu/WoS/SearchBase.pm
Criterion Covered Total %
statement 18 62 29.0
branch 0 10 0.0
condition 0 3 0.0
subroutine 6 17 35.2
pod 0 1 0.0
total 24 93 25.8


line stmt bran cond sub pod time code
1             package Catmandu::WoS::SearchBase;
2              
3 5     5   2716 use Catmandu::Sane;
  5         45  
  5         38  
4              
5             our $VERSION = '0.0302';
6              
7 5     5   1030 use Moo::Role;
  5         8  
  5         32  
8 5     5   3876 use URI::Escape qw(uri_escape);
  5         6234  
  5         259  
9 5     5   589 use XML::LibXML;
  5         38816  
  5         29  
10 5     5   663 use XML::LibXML::XPathContext;
  5         9  
  5         91  
11 5     5   31 use namespace::clean;
  5         9  
  5         24  
12              
13             with 'Catmandu::Importer';
14              
15             has username => (is => 'ro');
16             has password => (is => 'ro');
17             has session_id => (is => 'lazy');
18              
19             requires '_search_content';
20             requires '_retrieve_content';
21             requires '_search_response_type';
22             requires '_retrieve_response_type';
23             requires '_find_records';
24              
25             sub _auth_url {
26 0     0     my ($self) = @_;
27              
28 0           'http://'
29             . uri_escape($self->username) . ':'
30             . uri_escape($self->password)
31             . '@search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate';
32             }
33              
34             sub _auth_ns {
35 0     0     state $ns = {
36             'soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
37             'ns2' => 'http://auth.cxf.wokmws.thomsonreuters.com',
38             };
39             }
40              
41             sub _auth_content {
42 0     0     state $content = <<EOF;
43             <soapenv:Envelope
44             xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
45             xmlns:auth="http://auth.cxf.wokmws.thomsonreuters.com">
46             <soapenv:Header/>
47             <soapenv:Body>
48             <auth:authenticate/>
49             </soapenv:Body>
50             </soapenv:Envelope>
51             EOF
52             }
53              
54             sub _search_url {
55 0     0     state $url = 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearch';
56             }
57              
58             sub _search_ns {
59 0     0     state $ns = {
60             'soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
61             'ns2' => 'http://woksearch.v3.wokmws.thomsonreuters.com',
62             };
63             }
64              
65             sub _soap_request {
66 0     0     my ($self, $url, $ns, $content, $session_id) = @_;
67              
68 0           my $headers = ['Content-Type' => "text/xml; charset=UTF-8"];
69              
70 0 0         if ($session_id) {
71 0           push @$headers, 'Cookie', qq|SID="$session_id"|;
72             }
73              
74 0           my $res_content = $self->_http_request('POST', $url, $headers, $content,
75             $self->_http_timing_tries,);
76              
77 0           my $doc = XML::LibXML->new(huge => 1)->load_xml(string => $res_content);
78 0           my $xpc = XML::LibXML::XPathContext->new($doc);
79 0           $xpc->registerNs($_ => $ns->{$_}) for keys %$ns;
80 0           $xpc;
81             }
82              
83             sub _build_session_id {
84 0     0     my ($self) = @_;
85              
86 0           my $xpc = $self->_soap_request($self->_auth_url, $self->_auth_ns,
87             $self->_auth_content,);
88              
89 0           my $session_id = $xpc->findvalue(
90             '/soap:Envelope/soap:Body/ns2:authenticateResponse/return');
91              
92 0           return $session_id;
93             }
94              
95             sub _search {
96 0     0     my ($self, $start, $limit) = @_;
97              
98 0           my $response_type = $self->_search_response_type;
99              
100 0           my $xpc
101             = $self->_soap_request($self->_search_url, $self->_search_ns,
102             $self->_search_content($start, $limit),
103             $self->session_id);
104              
105 0           my $recs = $self->_find_records($xpc, $response_type);
106 0           my $total = $xpc->findvalue(
107             "/soap:Envelope/soap:Body/ns2:$response_type/return/recordsFound");
108 0           my $query_id = $xpc->findvalue(
109             "/soap:Envelope/soap:Body/ns2:$response_type/return/queryId");
110              
111 0           return $recs, $total, $query_id;
112             }
113              
114             sub _retrieve {
115 0     0     my ($self, $query_id, $start, $limit) = @_;
116              
117 0           my $xpc
118             = $self->_soap_request($self->_search_url, $self->_search_ns,
119             $self->_retrieve_content($query_id, $start, $limit),
120             $self->session_id);
121              
122 0           $self->_find_records($xpc, $self->_retrieve_response_type);
123             }
124              
125             sub generator {
126 0     0 0   my ($self) = @_;
127              
128             sub {
129 0     0     state $recs = [];
130 0           state $query_id;
131 0           state $start = 1;
132 0           state $limit = 100;
133 0           state $total;
134              
135 0 0         unless (@$recs) {
136 0 0 0       return if defined $total && $start > $total;
137              
138 0 0         if (defined $query_id) {
139 0           $recs = $self->_retrieve($query_id, $start, $limit);
140             }
141             else {
142 0           ($recs, $total, $query_id) = $self->_search($start, $limit);
143 0 0         $total || return;
144             }
145              
146 0           $start += $limit;
147             }
148              
149 0           shift @$recs;
150 0           };
151             }
152              
153             1;