File Coverage

blib/lib/WebService/Lucene/Index.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::Index;
2              
3 1     1   6853 use strict;
  1         3  
  1         42  
4 1     1   6 use warnings;
  1         4  
  1         38  
5              
6 1     1   6 use base qw( WebService::Lucene::Client Class::Accessor::Fast );
  1         2  
  1         96  
7              
8             use URI;
9             use Carp qw( croak );
10             use WebService::Lucene::XOXOParser;
11             use WebService::Lucene::Results;
12             use WebService::Lucene::Document;
13             use XML::Atom::Entry;
14             use HTTP::Request;
15             use WWW::OpenSearch;
16             use Encode ();
17              
18             __PACKAGE__->mk_accessors(
19             qw(
20             base_url name properties_ref _opensearch_client
21             )
22             );
23              
24             =head1 NAME
25              
26             WebService::Lucene::Index - Object to represent a Lucene Index
27              
28             =head1 SYNOPSIS
29              
30             # Index @ $url
31             $index = WebService::Lucene::Index->new( $url );
32            
33             # Get most recently modified documents
34             $results = $index->list;
35            
36             # Search the index
37             $results = $index->search( 'foo' );
38            
39             # Get a document
40             $doc = $index->get_document( $id );
41            
42             # Create a document
43             $doc = $index->create_document( $doc );
44            
45             # Delete the index
46             $index->delete;
47              
48             =head1 DESCRIPTION
49              
50             The module represents a Lucene Index.
51              
52             =head1 METHODS
53              
54             =head2 new( $url )
55              
56             Create a new Index object located at C<$url>. Note, this will
57             not actually create the index -- see C to do that.
58              
59             =cut
60              
61             sub new {
62             my ( $class, $url ) = @_;
63              
64             croak( "No URL specified" ) unless $url;
65              
66             if ( !ref $url ) {
67             $url =~ s{/?$}{/};
68             $url = URI->new( $url );
69             }
70              
71             my ( $name ) = $url =~ m{/([^/]+)/?$};
72              
73             my $self = $class->SUPER::new;
74             $self->base_url( $url );
75             $self->name( $name );
76              
77             return $self;
78             }
79              
80             =head2 base_url( [$url] )
81              
82             Accessor for the index's url.
83              
84             =head2 name( [$name] )
85              
86             Accessor for the index's name.
87              
88             =head2 properties( [$properties] )
89              
90             Accessor for the index's properties.
91              
92             =cut
93              
94             sub properties {
95             my $self = shift;
96              
97             if ( !$self->properties_ref ) {
98             $self->_fetch_index_properties;
99             }
100              
101             return $self->properties_ref;
102             }
103              
104             =head2 _fetch_index_properties( )
105              
106             Fetches the C entry and sends the contents
107             to C<_parse_index_properties>.
108              
109             =cut
110              
111             sub _fetch_index_properties {
112             my ( $self ) = @_;
113             my $entry = $self->getEntry(
114             URI->new_abs( 'index.properties', $self->base_url ) );
115             $self->_parse_index_properties( $entry->content->body );
116             }
117              
118             =head2 _parse_index_properties( $xml )
119              
120             Parses the XOXO document and sets the C accessor.
121              
122             =cut
123              
124             sub _parse_index_properties {
125             my ( $self, $xml ) = @_;
126              
127             $self->properties_ref(
128             { map { $_->{ name } => $_->{ value } }
129             WebService::Lucene::XOXOParser->parse( $xml )
130             }
131             );
132             }
133              
134             =head2 delete( )
135              
136             Deletes the current index.
137              
138             =cut
139              
140             sub delete {
141             my ( $self ) = @_;
142             $self->deleteEntry( $self->base_url );
143             }
144              
145             =head2 update( )
146              
147             Updates the C file with the current set of properties.
148              
149             =cut
150              
151             sub update {
152             my ( $self ) = @_;
153             $self->updateEntry( URI->new_abs( 'index.properties', $self->base_url ),
154             $self->_properties_as_entry );
155             }
156              
157             =head2 facets( $facets, [$params] )
158              
159             Give a facet (or set of facets as an array reference), it will
160             return a L object with their details. You
161             can pass any number of parameters that will be serialized as query
162             string arguments.
163              
164             =cut
165              
166             sub facets {
167             my ( $self, $facet, $params ) = @_;
168              
169             my $name = ref $facet ? join( ',', @$facet ) : $facet;
170             my $client = $self->opensearch_client;
171              
172             my $os_url = $client->description->get_best_url;
173             my $url = $os_url->prepare_query( $params );
174             $url->path( $url->path . "/facets/$name" );
175              
176             return WebService::Lucene::Results->new_from_feed(
177             $self->getFeed( $url ) );
178             }
179              
180             =head2 list( [$params] )
181              
182             Returns a L object with a list of the recently updated documents.
183              
184             =cut
185              
186             sub list {
187             my ( $self, $params ) = @_;
188             my $url = $self->base_url->clone;
189             $url->query_form( $params ) if $params;
190             return WebService::Lucene::Results->new_from_feed(
191             $self->getFeed( $url ) );
192             }
193              
194             =head2 optimize( )
195              
196             Optimizes the index.
197              
198             =cut
199              
200             sub optimize {
201             my ( $self ) = @_;
202             my $request = HTTP::Request->new( PUT => $self->base_url . '?optimize' );
203             return $self->make_request( $request );
204             }
205              
206             =head2 create( )
207              
208             Sends a create query to the server for the given index.
209              
210             =cut
211              
212             sub create {
213             my ( $self ) = @_;
214             my $name = $self->name;
215             my $url = $self->base_url;
216              
217             $url =~ s{$name/?$}{};
218              
219             $self->createEntry( $url, $self->_properties_as_entry );
220              
221             return $self;
222             }
223              
224             =head2 add_document( $document )
225              
226             Adds C<$document> to the index.
227              
228             =cut
229              
230             sub add_document {
231             my ( $self, $document ) = @_;
232             $document->base_url( URI->new_abs( 'new', $self->base_url ) );
233             return $document->create;
234             }
235              
236             =head2 get_document( $id )
237              
238             Returns a L.
239              
240             =cut
241              
242             sub get_document {
243             my ( $self, $id ) = @_;
244             my $entry = $self->getEntry( URI->new_abs( $id, $self->base_url ) );
245              
246             return WebService::Lucene::Document->new_from_entry( $entry );
247             }
248              
249             =head2 delete_document( $id )
250              
251             Deletes a document from the index
252              
253             =cut
254              
255             sub delete_document {
256             my ( $self, $id ) = @_;
257             my $document = WebService::Lucene::Document->new;
258              
259             $document->base_url( URI->new_abs( $id, $self->base_url ) );
260             return $document->delete;
261             }
262              
263             =head2 _properties_as_entry( )
264              
265             Constructs an L object representing the index's properties.
266              
267             =cut
268              
269             sub _properties_as_entry {
270             my ( $self ) = @_;
271              
272             my $entry = XML::Atom::Entry->new;
273             $entry->title( $self->name );
274              
275             my $props = $self->properties_ref;
276             my @properties = map +{ name => $_, value => $props->{ $_ } },
277             keys %$props;
278             my $xml = WebService::Lucene::XOXOParser->construct( @properties );
279              
280             $entry->content( $xml );
281             $entry->content->type( 'xhtml' );
282              
283             return $entry;
284             }
285              
286             =head2 opensearch_client( )
287              
288             returns an WWW::OpenSearch object for the index.
289              
290             =cut
291              
292             sub opensearch_client {
293             my ( $self ) = @_;
294              
295             if ( !$self->_opensearch_client ) {
296             $self->_opensearch_client(
297             WWW::OpenSearch->new(
298             URI->new_abs( 'opensearchdescription.xml', $self->base_url )
299             )
300             );
301             }
302              
303             return $self->_opensearch_client;
304             }
305              
306             =head2 search( $query, [$params] )
307              
308             Searches the index for C<$query>. Pass any additional parameters as
309             a hashref.
310              
311             =cut
312              
313             sub search {
314             my ( $self, $query, $params ) = @_;
315              
316             my $client = $self->opensearch_client;
317              
318             Encode::_utf8_off( $query );
319             my $response = $client->search( $query, $params );
320             Encode::_utf8_on( $query );
321              
322             return WebService::Lucene::Results->new_from_opensearch( $response );
323             }
324              
325             =head2 exists( )
326              
327             True if the index exists on the server, otherwise false is returned.
328              
329             =cut
330              
331             sub exists {
332             my ( $self ) = @_;
333             my $request = HTTP::Request->new( HEAD => $self->base_url );
334             my $response = eval { $self->make_request( $request ); };
335              
336             if ( my $e = WebService::Lucene::Exception->caught ) {
337             return 0 if $e->response->code eq '404';
338             $e->rethrow;
339             }
340              
341             return 1;
342             }
343              
344             =head1 AUTHORS
345              
346             =over 4
347              
348             =item * Brian Cassidy Ebrian.cassidy@nald.caE
349              
350             =item * Adam Paynter Eadam.paynter@nald.caE
351              
352             =back
353              
354             =head1 COPYRIGHT AND LICENSE
355              
356             Copyright 2006-2009 National Adult Literacy Database
357              
358             This library is free software; you can redistribute it and/or modify
359             it under the same terms as Perl itself.
360              
361             =cut
362              
363             1;