File Coverage

blib/lib/WebService/Lucene.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;
2              
3 2     2   52178 use strict;
  2         6  
  2         82  
4 2     2   12 use warnings;
  2         4  
  2         70  
5              
6 2     2   19 use base qw( WebService::Lucene::Client Class::Accessor::Fast );
  2         8  
  2         1233  
7              
8             use URI;
9             use Carp qw( croak );
10             use WebService::Lucene::Index;
11             use WebService::Lucene::XOXOParser;
12             use XML::LibXML;
13             use Scalar::Util ();
14              
15             our $VERSION = '0.10';
16              
17             __PACKAGE__->mk_accessors(
18             qw(
19             base_url indices_ref properties_ref title_info
20             service_doc_fetched
21             )
22             );
23              
24             =head1 NAME
25              
26             WebService::Lucene - Module to interface with the Lucene indexing webservice
27              
28             =head1 SYNOPSIS
29              
30             # Connect to the web service
31             $ws = WebService::Lucene->new( $url );
32            
33             # Create an index
34             $ndex = $ws->create_index( $index );
35            
36             # Get a particular index
37             $index = $ws->get_index( $name );
38            
39             # Index a document
40             $document = $index->add_document( $document );
41            
42             # Get a document
43             $document = $index->get_document( $id );
44            
45             # Delete the document
46             $document->delete;
47            
48             # Search an index
49             $results = $index->search( $query );
50            
51             # Get documents from search
52             @documents = $results->documents;
53            
54             # Delete an index
55             $index->delete;
56              
57             =head1 DESCRIPTION
58              
59             This module is a Perl API in to the Lucene indexing web service.
60             http://lucene-ws.net/
61              
62             =head1 METHODS
63              
64             =head2 new( $url )
65              
66             This method will connect to the Lucene Web Service located at C<$url>.
67              
68             my $ws = WebService::Lucene->new( 'http://localhost:8080/lucene/' );
69              
70             =cut
71              
72             sub new {
73             my ( $class, $url ) = @_;
74              
75             croak( "No URL specified" ) unless $url;
76              
77             if ( !ref $url ) {
78             $url =~ s{/?$}{/};
79             $url = URI->new( $url );
80             }
81              
82             my $self = $class->SUPER::new;
83             $self->base_url( $url );
84             $self->indices_ref( {} );
85              
86             return $self;
87             }
88              
89             =head2 base_url( [$url] )
90              
91             Accessor for the base url of the service.
92              
93             =head2 get_index( $name )
94              
95             Retuens an L object for C<$name>.
96              
97             =cut
98              
99             sub get_index {
100             my ( $self, $name ) = @_;
101             my $indices_ref = $self->indices_ref;
102              
103             return $name if Scalar::Util::blessed $name;
104              
105             if ( ref $name ) {
106             $name = join( ',',
107             map { Scalar::Util::blessed $_ ? $_->name : $_ } @$name );
108             }
109              
110             if ( my $index = $indices_ref->{ $name } ) {
111             return $index;
112             }
113              
114             # make sure it ends in a slash
115             my $urlname = $name;
116             $urlname =~ s{/?$}{/};
117             $indices_ref->{ $name } = WebService::Lucene::Index->new(
118             URI->new_abs( $urlname, $self->base_url ) );
119              
120             return $indices_ref->{ $name };
121             }
122              
123             =head2 indexes( )
124              
125             Alias for C
126              
127             =head2 indices( )
128              
129             Returns an array of L objects.
130              
131             =cut
132              
133             *indexes = \&indices;
134              
135             sub indices {
136             my $self = shift;
137              
138             if ( !$self->service_doc_fetched ) {
139             $self->_fetch_service_document;
140             }
141              
142             my $indices = $self->indices_ref;
143              
144             # filter out multi-indicies
145             return map { $indices->{ $_ } } grep { $_ !~ /,/ } keys %$indices;
146             }
147              
148             =head2 properties( [$properties] )
149              
150             Hash reference to a list of properties for the service.
151              
152             =cut
153              
154             sub properties {
155             my $self = shift;
156              
157             if ( !$self->properties_ref ) {
158             $self->_fetch_service_properties;
159             }
160              
161             return $self->properties_ref;
162             }
163              
164             =head2 _fetch_service_properties( )
165              
166             Grabs the C documents and sends the contents
167             to C<_parse_service_properties>.
168              
169             =cut
170              
171             sub _fetch_service_properties {
172             my ( $self ) = @_;
173             my $entry = $self->getEntry(
174             URI->new_abs( 'service.properties', $self->base_url ) );
175             $self->_parse_service_properties( $entry->content->body );
176             }
177              
178             =head2 _parse_service_properties( $xml )
179              
180             Parses the XML and populates the object's C
181              
182             =cut
183              
184             sub _parse_service_properties {
185             my ( $self, $xml ) = @_;
186              
187             $self->properties_ref(
188             { map { $_->{ name } => $_->{ value } }
189             WebService::Lucene::XOXOParser->parse( $xml )
190             }
191             );
192             }
193              
194             =head2 _fetch_service_document( )
195              
196             Connects to the service url and passes the contents on to
197             C<_parse_service_document>.
198              
199             =cut
200              
201             sub _fetch_service_document {
202             my ( $self ) = @_;
203             $self->_parse_service_document(
204             $self->_fetch_content( $self->base_url ) );
205             $self->service_doc_fetched( 1 );
206             }
207              
208             =head2 _parse_service_document( $xml )
209              
210             Parses the Atom Publishing Protocol introspection document and populates
211             the service's C.
212              
213             =cut
214              
215             sub _parse_service_document {
216             my ( $self, $xml ) = @_;
217              
218             my $parser = XML::LibXML->new;
219             my $doc = $parser->parse_string( $xml );
220             my $indices = $self->indices_ref;
221              
222             my ( $workspace )
223             = $doc->documentElement->getChildrenByTagName( 'workspace' );
224              
225             my( $title ) = $workspace->getElementsByLocalName( 'title' );
226             $self->title_info( $title->textContent );
227              
228             for my $collection ( $workspace->getChildrenByTagName( 'collection' ) ) {
229             my $url = $collection->getAttributeNode( 'href' )->value;
230             my ( $name ) = $url =~ m{/([^/]+)/?$};
231             next if exists $indices->{ $name };
232             $indices->{ $name } = WebService::Lucene::Index->new( $url );
233             }
234             }
235              
236             =head2 title( [$title] )
237              
238             Accessor for the title of the service.
239              
240             =cut
241              
242             sub title {
243             my ( $self ) = @_;
244              
245             if ( !$self->service_doc_fetched ) {
246             $self->_fetch_service_document;
247             }
248              
249             return $self->title_info;
250             }
251              
252             =head2 _fetch_content( $url )
253              
254             Shortcut for fetching the content at C<$url>.
255              
256             =cut
257              
258             sub _fetch_content {
259             my ( $self, $url ) = @_;
260              
261             my $response = $self->{ ua }->get( $url );
262              
263             return $response->content;
264             }
265              
266             =head2 create_index( $name )
267              
268             Creates the index on the server and returns the
269             L object.
270              
271             =cut
272              
273             sub create_index {
274             my ( $self, $name ) = @_;
275             my $index = $self->get_index( $name );
276             return $index->create;
277             }
278              
279             =head2 delete_index( $name )
280              
281             Deletes an index.
282              
283             =cut
284              
285             sub delete_index {
286             my ( $self, $name ) = @_;
287             my $index = $self->get_index( $name );
288             return $index->delete;
289             }
290              
291             =head2 update( )
292              
293             Updates the C document.
294              
295             =cut
296              
297             sub update {
298             my ( $self ) = @_;
299             $self->updateEntry( URI->new_abs( 'service.properties', $self->base_url ),
300             $self->_properties_as_entry );
301             }
302              
303             =head2 _properties_as_entry( )
304              
305             Genereates an L suitable for updating
306             the C document.
307              
308             =cut
309              
310             sub _properties_as_entry {
311             my ( $self ) = @_;
312              
313             my $entry = XML::Atom::Entry->new;
314             $entry->title( 'service.properties' );
315              
316             my $props = $self->properties_ref;
317             my @properties = map +{ name => $_, value => $props->{ $_ } },
318             keys %$props;
319             my $xml = WebService::Lucene::XOXOParser->construct( @properties );
320              
321             $entry->content( $xml );
322             $entry->content->type( 'xhtml' );
323              
324             return $entry;
325             }
326              
327             =head2 search( $indices, $query, [$params] )
328              
329             Searches one or more indices for C<$query>. Returns an
330             L object.
331              
332             my $results = $ws->search( [ 'index1', 'index2' ], 'foo' );
333              
334             =cut
335              
336             sub search {
337             my ( $self, $name, @rest ) = @_;
338             return $self->get_index( $name )->search( @rest );
339             }
340              
341             =head2 facets( $indices, [$params] )
342              
343             Gets facets for one or more indices. Returns an
344             L object.
345              
346             my $results = $ws->facets( [ 'index1', 'index2' ] );
347              
348             =cut
349              
350             sub facets {
351             my ( $self, $name, @rest ) = @_;
352             return $self->get_index( $name )->facets( @rest );
353             }
354              
355             =head1 SEE ALSO
356              
357             =over 4
358              
359             =item * L
360              
361             =item * L
362              
363             =item * http://lucene-ws.net/
364              
365             =back
366              
367             =head1 AUTHORS
368              
369             Brian Cassidy Ebricas@cpan.orgE
370              
371             Adam Paynter Eadapay@cpan.orgE
372              
373             =head1 COPYRIGHT AND LICENSE
374              
375             Copyright 2006-2009 National Adult Literacy Database
376              
377             This library is free software; you can redistribute it and/or modify
378             it under the same terms as Perl itself.
379              
380             =cut
381              
382             1;