File Coverage

blib/lib/WebService/Lucene/Results.pm
Criterion Covered Total %
statement 9 9 100.0
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 12 12 100.0


line stmt bran cond sub pod time code
1             package WebService::Lucene::Results;
2              
3 1     1   1940 use strict;
  1         3  
  1         41  
4 1     1   6 use warnings;
  1         3  
  1         33  
5              
6 1     1   6 use base qw( WebService::Lucene::Client Class::Accessor::Fast );
  1         2  
  1         99  
7              
8             use WebService::Lucene::Document;
9             use WebService::Lucene::Iterator;
10             use WebService::Lucene::Exception;
11             use Encode qw();
12             use XML::Atom::Util;
13              
14             use Carp;
15              
16             __PACKAGE__->mk_accessors( qw( pager documents_ref object ) );
17              
18             =head1 NAME
19              
20             WebService::Lucene::Results - Results from a search or list operation
21              
22             =head1 SYNOPSIS
23              
24             # documents
25             @docs = $results->documents;
26            
27             # iterator
28             $docs = $results->documents;
29            
30             # Data::Page object
31             $pager = $results->pager;
32            
33             # next page
34             $results = $results->next_page;
35            
36             # previous page
37             $results = $results->previous_page;
38              
39             =head1 DESCRIPTION
40              
41             Wraps a list of documents and a L object.
42              
43             =head1 METHODS
44              
45             =head2 new( )
46              
47             Creates an empty results object.
48              
49             =cut
50              
51             sub new {
52             my $class = shift;
53             my $self = $class->SUPER::new;
54              
55             $self->documents_ref( [] );
56              
57             return $self;
58             }
59              
60             =head2 new_from_feed( $feed )
61              
62             Generates a results object from an L object.
63              
64             =cut
65              
66             sub new_from_feed {
67             my ( $class, $object ) = @_;
68             $class = ref $class if ref $class;
69             my $self = $class->new;
70             my @entries = $object->entries;
71              
72             $self->documents_ref( [ map { $_->{ entry } || $_ } @entries ] );
73             $self->object( $object );
74             return $self;
75             }
76              
77             =head2 new_from_opensearch( $opensearch )
78              
79             Generates a results object from an L object.
80              
81             =cut
82              
83             sub new_from_opensearch {
84             my ( $class, $object ) = @_;
85              
86             if ( !$object->is_success ) {
87             WebService::Lucene::Exception->throw( $object );
88             }
89              
90             my $self = $class->new_from_feed( $object->feed );
91              
92             $self->pager( $object->pager );
93             $self->object( $object );
94              
95             return $self;
96             }
97              
98             =head2 object( [$object] )
99              
100             Accessor for the original results object.
101              
102             =head2 pager( [$pager] )
103              
104             Accessor for the L object.
105              
106             =head2 documents_ref( [$documents] )
107              
108             Accessor for an array ref of documents.
109              
110             =head2 documents( )
111              
112             Returns an interator in scalar context or an array of documents
113             in list context.
114              
115             =cut
116              
117             sub documents {
118             my $self = shift;
119              
120             if ( wantarray ) {
121             my @documents;
122             for ( @{ $self->documents_ref } ) {
123             push @documents,
124             WebService::Lucene::Document->new_from_entry( $_ );
125             }
126              
127             return @documents;
128             }
129             else {
130             return WebService::Lucene::Iterator->new( $self->documents_ref );
131             }
132             }
133              
134             =head2 next_page( )
135              
136             Goes to the next page of results.
137              
138             =cut
139              
140             sub next_page {
141             my $self = shift;
142             my $object = $self->object;
143              
144             if ( $object->can( 'next_page' ) ) {
145             return $self->new_from_opensearch( $object->next_page );
146             }
147              
148             return $self->_fetch( $self->_get_link( 'next' ) );
149             }
150              
151             =head2 previous_page( )
152              
153             Goes to the previous page of results.
154              
155             =cut
156              
157             sub previous_page {
158             my $self = shift;
159             my $object = $self->object;
160              
161             if ( $object->can( 'previous_page' ) ) {
162             return $self->new_from_opensearch( $object->previous_page );
163             }
164              
165             return $self->_fetch( $self->_get_link( 'previous' ) );
166             }
167              
168             =head2 suggestion
169              
170             Returns the C field with C if it exists.
171             In list context, returns the full list. In scalar context only the first
172             suggestion is returned.
173              
174             =head2 suggestions
175              
176             Alias for C.
177              
178             =cut
179              
180             *suggestions = \&suggestion;
181              
182             sub suggestion {
183             my $self = shift;
184             return unless $self->object->can( 'feed' );
185              
186             my @vals;
187             for ( $self->_os_nodelist( 'Query' ) ) {
188             next unless $_->getAttribute( 'rel' ) eq 'correction';
189             my $val = $_->getAttribute( 'searchTerms' );
190             Encode::_utf8_on( $val );
191             push @vals, $val;
192             }
193             return wantarray ? @vals : $vals[ 0 ];
194             }
195              
196             sub _os_nodelist {
197             my $self = shift;
198             my $elem = shift;
199             my $object = $self->object;
200             my $ns = $object->request->opensearch_url->ns;
201              
202             return XML::Atom::Util::nodelist( $object->feed->{ atom }->elem, $ns,
203             $elem );
204             }
205              
206             =head2 _get_link( $type )
207              
208             Attempts to get a link tag of type C<$type> from an Atom feed.
209              
210             =cut
211              
212             sub _get_link {
213             my $self = shift;
214             my $type = shift;
215             my $feed = $self->object;
216              
217             return unless $feed;
218              
219             for ( $feed->link ) {
220             return $_->href if $_->rel eq $type;
221             }
222             }
223              
224             =head2 _fetch( $url )
225              
226             Attempts to get an Atom feed from C<$url> and send it
227             to C.
228              
229             =cut
230              
231             sub _fetch {
232             my $self = shift;
233             my $url = shift;
234              
235             return undef unless $url;
236              
237             my $feed = $self->getFeed( $url );
238              
239             croak "Error getting list: " . $self->errstr unless $feed;
240              
241             return $self->new_from_feed( $feed );
242             }
243              
244             =head1 AUTHORS
245              
246             =over 4
247              
248             =item * Brian Cassidy Ebrian.cassidy@nald.caE
249              
250             =item * Adam Paynter Eadam.paynter@nald.caE
251              
252             =back
253              
254             =head1 COPYRIGHT AND LICENSE
255              
256             Copyright 2006-2009 National Adult Literacy Database
257              
258             This library is free software; you can redistribute it and/or modify
259             it under the same terms as Perl itself.
260              
261             =cut
262              
263             1;