package Biblio::COUNTER::Processor; use strict; use warnings; use Biblio::COUNTER; # A class designed to be inherited from for OO-style event handling sub new { my ($cls, %args) = @_; my $self = bless { 'ignore' => {}, %args, }, $cls; return $self; } sub ignore { my ($self, @what) = @_; $self->{'ignore'}->{$_} = 1 for @what; } sub run { my ($self, $report) = @_; my $fh; $self->{'file'} = $report; if (ref($report) eq '') { # Assume $report is a file name if ($report eq '-') { $fh = \*STDIN; } else { open $fh, '<', $report or die "Can't open report '$report': $!"; } $report = Biblio::COUNTER->report($fh); } elsif ($report->isa('Biblio::COUNTER::Report')) { # Nothing special to do } else { # Assume it's a filehandle $report = Biblio::COUNTER->report($report); } $report->{'file'} = $self->{'file'}; my $ignore = $self->{'ignore'}; $report->{'callback'} = { '*' => sub { my ($report, $callback_name, @args) = @_; if (!$ignore->{$callback_name} && defined(my $code = $self->can($callback_name))) { $code->($self, $report, @args); } }, }; $report->process; close $fh if defined $fh; return $report; } 1; =pod =head1 NAME Biblio::COUNTER::Processor - superclass for Biblio::COUNTER processors =head1 SYNOPSIS # Use use Biblio::COUNTER::Processor; $processor = Biblio::COUNTER::Processor->new; $processor->ignore(@events); $report = $processor->run; # Subclass use MyProcessor; @MyProcessor::ISA = qw(Biblio::COUNTER::Processor); # Event handlers sub begin_report { my ($self, $report) = @_; # etc. } sub count { my ($self, $report, $scope, $field, $period, $val) = @_; # etc. } # etc. =head1 DESCRIPTION B<Biblio::COUNTER::Processor> is an inheritable class that provides an intermediate interface to L<Biblio::COUNTER|Biblio::COUNTER>. When used on its own, it does nothing; subclasses must define handlers for the various events (e.g., C<begin_report> or C<count>) that are triggered as a report is processed. Event-handling methods (if defined) are invoked with the arguments documented in L<Biblio::COUNTER>, except that an additional argument (the instance of the L<Biblio::COUNTER::Processor|Biblio::COUNTER::Processor> subclass) is prepended. For a class that actually B<does> something when events are triggered, see L<Biblio::COUNTER::Processor::Simple|Biblio::COUNTER::Processor::Simple>. =head1 METHODS =over 4 =item B<new> $processor = Biblio::COUNTER::Processor->new; Create a new processor. =item B<run>(I<$file>) $report = $processor->run($what); Process the given report. I<$what> may be a file handle, the name of a file, or an instance of (a subclass of) L<Biblio::COUNTER::Report|Biblio::COUNTER::Report>. A L<Biblio::COUNTER::Report|Biblio::COUNTER::Report> object will be instantiated and its B<process> method invoked; each time an event is triggered, a method with the event's name (e.g., C<begin_record> or C<cant_fix>) is invoked B<if it is defined>. Since this class doesn't define any such methods, the default behavior when an event is triggered is to do nothing. =item B<ignore>(I<@events>) $processor->ignore(qw/line input output/); Specify the events to ignore. The various events are documented in L<Biblio::COUNTER>. =back =head1 INHERITANCE B<Biblio::COUNTER::Processor> is designed to be inheritable; in fact, it doesn't do anything on its own (unless you count I<ignoring events> as doing something). =head1 BUGS There are no known bugs. Please report bugs to the author via e-mail (see below). =head1 AUTHOR Paul Hoffman (nkuitse AT cpan DOT org) =head1 COPYRIGHT Copyright 2008 Paul M. Hoffman. This is free software, and is made available under the same terms as Perl itself. =head1 SEE ALSO L<Biblio::COUNTER> L<Biblio::COUNTER::Report> L<Biblio::COUNTER::Report::Processor::Simple>